Merge pull request #1872 from sateesh-chodapuneedi/pr-cloudstack-3223

CLOUDSTACK-3223 Exception observed while creating CPVM in VMware Setup with DVS
diff --git a/.travis.yml b/.travis.yml
index da81633..b8fbf0a 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -48,6 +48,7 @@
              smoke/test_list_ids_parameter
              smoke/test_loadbalance
              smoke/test_login
+             smoke/test_metrics_api
              smoke/test_multipleips_per_nic
              smoke/test_network
              smoke/test_network_acl
diff --git a/agent/pom.xml b/agent/pom.xml
index 5d5a189..4bfd5a7 100644
--- a/agent/pom.xml
+++ b/agent/pom.xml
@@ -23,7 +23,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
   </parent>
   <dependencies>
     <dependency>
diff --git a/api/pom.xml b/api/pom.xml
index 0f773cd..9524e2d 100644
--- a/api/pom.xml
+++ b/api/pom.xml
@@ -23,7 +23,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
   </parent>
   <dependencies>
     <dependency>
diff --git a/api/src/org/apache/cloudstack/api/command/admin/cluster/ListClustersCmd.java b/api/src/org/apache/cloudstack/api/command/admin/cluster/ListClustersCmd.java
index 432ca92..74ad764 100644
--- a/api/src/org/apache/cloudstack/api/command/admin/cluster/ListClustersCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/admin/cluster/ListClustersCmd.java
@@ -125,18 +125,22 @@
         return s_name;
     }
 
-    @Override
-    public void execute() {
+    protected List<ClusterResponse> getClusterResponses() {
         Pair<List<? extends Cluster>, Integer> result = _mgr.searchForClusters(this);
-        ListResponse<ClusterResponse> response = new ListResponse<ClusterResponse>();
         List<ClusterResponse> clusterResponses = new ArrayList<ClusterResponse>();
         for (Cluster cluster : result.first()) {
             ClusterResponse clusterResponse = _responseGenerator.createClusterResponse(cluster, showCapacities);
             clusterResponse.setObjectName("cluster");
             clusterResponses.add(clusterResponse);
         }
+        return clusterResponses;
+    }
 
-        response.setResponses(clusterResponses, result.second());
+    @Override
+    public void execute() {
+        List<ClusterResponse> clusterResponses = getClusterResponses();
+        ListResponse<ClusterResponse> response = new ListResponse<ClusterResponse>();
+        response.setResponses(clusterResponses, clusterResponses.size());
         response.setResponseName(getCommandName());
         this.setResponseObject(response);
     }
diff --git a/api/src/org/apache/cloudstack/api/command/admin/host/ListHostsCmd.java b/api/src/org/apache/cloudstack/api/command/admin/host/ListHostsCmd.java
index 424fc05..3391fdc 100644
--- a/api/src/org/apache/cloudstack/api/command/admin/host/ListHostsCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/admin/host/ListHostsCmd.java
@@ -132,6 +132,10 @@
         return state;
     }
 
+    public void setType(String type) {
+        this.type = type;
+    }
+
     public String getType() {
         return type;
     }
@@ -198,19 +202,16 @@
         return ApiCommandJobType.Host;
     }
 
-    @Override
-    public void execute() {
-        ListResponse<HostResponse> response = null;
+    protected ListResponse<HostResponse> getHostResponses() {
+        ListResponse<HostResponse> response = new ListResponse<>();
         if (getVirtualMachineId() == null) {
             response = _queryService.searchForServers(this);
         } else {
             Pair<List<? extends Host>, Integer> result;
             Ternary<Pair<List<? extends Host>, Integer>, List<? extends Host>, Map<Host, Boolean>> hostsForMigration =
-                _mgr.listHostsForMigrationOfVM(getVirtualMachineId(), this.getStartIndex(), this.getPageSizeVal());
+                    _mgr.listHostsForMigrationOfVM(getVirtualMachineId(), this.getStartIndex(), this.getPageSizeVal());
             result = hostsForMigration.first();
             List<? extends Host> hostsWithCapacity = hostsForMigration.second();
-
-            response = new ListResponse<HostResponse>();
             List<HostResponse> hostResponses = new ArrayList<HostResponse>();
             for (Host host : result.first()) {
                 HostResponse hostResponse = _responseGenerator.createHostResponse(host, getDetails());
@@ -222,9 +223,14 @@
                 hostResponse.setObjectName("host");
                 hostResponses.add(hostResponse);
             }
-
             response.setResponses(hostResponses, result.second());
         }
+        return response;
+    }
+
+    @Override
+    public void execute() {
+        ListResponse<HostResponse> response = getHostResponses();
         response.setResponseName(getCommandName());
         this.setResponseObject(response);
     }
diff --git a/api/src/org/apache/cloudstack/api/response/HostResponse.java b/api/src/org/apache/cloudstack/api/response/HostResponse.java
index ab9c8c3..90fe800 100644
--- a/api/src/org/apache/cloudstack/api/response/HostResponse.java
+++ b/api/src/org/apache/cloudstack/api/response/HostResponse.java
@@ -458,4 +458,163 @@
 
     }
 
+    public String getName() {
+        return name;
+    }
+
+    public Status getState() {
+        return state;
+    }
+
+    public Date getDisconnectedOn() {
+        return disconnectedOn;
+    }
+
+    public Host.Type getHostType() {
+        return hostType;
+    }
+
+    public String getOsCategoryId() {
+        return osCategoryId;
+    }
+
+    public String getOsCategoryName() {
+        return osCategoryName;
+    }
+
+    public String getIpAddress() {
+        return ipAddress;
+    }
+
+    public String getZoneId() {
+        return zoneId;
+    }
+
+    public String getZoneName() {
+        return zoneName;
+    }
+
+    public String getPodId() {
+        return podId;
+    }
+
+    public String getPodName() {
+        return podName;
+    }
+
+    public String getVersion() {
+        return version;
+    }
+
+    public HypervisorType getHypervisor() {
+        return hypervisor;
+    }
+
+    public Integer getCpuSockets() {
+        return cpuSockets;
+    }
+
+    public Integer getCpuNumber() {
+        return cpuNumber;
+    }
+
+    public Long getCpuSpeed() {
+        return cpuSpeed;
+    }
+
+    public String getCpuUsed() {
+        return cpuUsed;
+    }
+
+    public Long getAverageLoad() {
+        return averageLoad;
+    }
+
+    public Long getNetworkKbsRead() {
+        return networkKbsRead;
+    }
+
+    public Long getNetworkKbsWrite() {
+        return networkKbsWrite;
+    }
+
+    public Long getMemoryTotal() {
+        return memoryTotal;
+    }
+
+    public Long getMemoryAllocated() {
+        return memoryAllocated;
+    }
+
+    public Long getMemoryUsed() {
+        return memoryUsed;
+    }
+
+    public List<GpuResponse> getGpuGroup() {
+        return gpuGroup;
+    }
+
+    public Long getDiskSizeTotal() {
+        return diskSizeTotal;
+    }
+
+    public Long getDiskSizeAllocated() {
+        return diskSizeAllocated;
+    }
+
+    public String getCapabilities() {
+        return capabilities;
+    }
+
+    public Date getLastPinged() {
+        return lastPinged;
+    }
+
+    public Long getManagementServerId() {
+        return managementServerId;
+    }
+
+    public String getClusterId() {
+        return clusterId;
+    }
+
+    public String getClusterName() {
+        return clusterName;
+    }
+
+    public String getClusterType() {
+        return clusterType;
+    }
+
+    public Boolean getLocalStorageActive() {
+        return localStorageActive;
+    }
+
+    public Date getCreated() {
+        return created;
+    }
+
+    public Date getRemoved() {
+        return removed;
+    }
+
+    public String getEvents() {
+        return events;
+    }
+
+    public Boolean getHasEnoughCapacity() {
+        return hasEnoughCapacity;
+    }
+
+    public Boolean getSuitableForMigration() {
+        return suitableForMigration;
+    }
+
+    public String getHypervisorVersion() {
+        return hypervisorVersion;
+    }
+
+    public Boolean getHaHost() {
+        return haHost;
+    }
 }
diff --git a/api/src/org/apache/cloudstack/api/response/NicResponse.java b/api/src/org/apache/cloudstack/api/response/NicResponse.java
index 7335836..7689123 100644
--- a/api/src/org/apache/cloudstack/api/response/NicResponse.java
+++ b/api/src/org/apache/cloudstack/api/response/NicResponse.java
@@ -16,15 +16,14 @@
 // under the License.
 package org.apache.cloudstack.api.response;
 
-import java.util.List;
-
+import com.cloud.serializer.Param;
+import com.cloud.vm.Nic;
+import com.google.gson.annotations.SerializedName;
 import org.apache.cloudstack.api.ApiConstants;
 import org.apache.cloudstack.api.BaseResponse;
 import org.apache.cloudstack.api.EntityReference;
 
-import com.cloud.serializer.Param;
-import com.cloud.vm.Nic;
-import com.google.gson.annotations.SerializedName;
+import java.util.List;
 
 @SuppressWarnings("unused")
 @EntityReference(value = Nic.class)
@@ -221,4 +220,79 @@
         this.nsxLogicalSwitchPort = nsxLogicalSwitchPort;
     }
 
+    public String getNetworkId() {
+        return networkId;
+    }
+
+    public String getNetworkName() {
+        return networkName;
+    }
+
+    public String getNetmask() {
+        return netmask;
+    }
+
+    public String getGateway() {
+        return gateway;
+    }
+
+    public String getIsolationUri() {
+        return isolationUri;
+    }
+
+    public String getBroadcastUri() {
+        return broadcastUri;
+    }
+
+    public String getTrafficType() {
+        return trafficType;
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    public Boolean getDefault() {
+        return isDefault;
+    }
+
+    public String getMacAddress() {
+        return macAddress;
+    }
+
+    public String getIpaddress() {
+        return ipaddress;
+    }
+
+    public String getIp6Gateway() {
+        return ip6Gateway;
+    }
+
+    public String getIp6Cidr() {
+        return ip6Cidr;
+    }
+
+    public String getIp6Address() {
+        return ip6Address;
+    }
+
+    public List<NicSecondaryIpResponse> getSecondaryIps() {
+        return secondaryIps;
+    }
+
+    public String getDeviceId() {
+        return deviceId;
+    }
+
+    public String getVmId() {
+        return vmId;
+    }
+
+    public String getNsxLogicalSwitch() {
+        return nsxLogicalSwitch;
+    }
+
+    public String getNsxLogicalSwitchPort() {
+        return nsxLogicalSwitchPort;
+    }
 }
diff --git a/api/src/org/apache/cloudstack/api/response/StoragePoolResponse.java b/api/src/org/apache/cloudstack/api/response/StoragePoolResponse.java
index 3571866..b7f7d0b 100644
--- a/api/src/org/apache/cloudstack/api/response/StoragePoolResponse.java
+++ b/api/src/org/apache/cloudstack/api/response/StoragePoolResponse.java
@@ -309,4 +309,12 @@
     public void setOverProvisionFactor(String overProvisionFactor) {
         this.overProvisionFactor = overProvisionFactor;
     }
+
+    public String getOverProvisionFactor() {
+        return overProvisionFactor;
+    }
+
+    public Boolean getSuitableForMigration() {
+        return suitableForMigration;
+    }
 }
diff --git a/api/src/org/apache/cloudstack/api/response/UserVmResponse.java b/api/src/org/apache/cloudstack/api/response/UserVmResponse.java
index b681d4f..2ff1eaa 100644
--- a/api/src/org/apache/cloudstack/api/response/UserVmResponse.java
+++ b/api/src/org/apache/cloudstack/api/response/UserVmResponse.java
@@ -813,4 +813,28 @@
     public void setOsTypeId(Long osTypeId) {
         this.osTypeId = osTypeId;
     }
+
+    public Set<Long> getTagIds() {
+        return tagIds;
+    }
+
+    public void setTagIds(Set<Long> tagIds) {
+        this.tagIds = tagIds;
+    }
+
+    public Map getDetails() {
+        return details;
+    }
+
+    public Boolean getDynamicallyScalable() {
+        return isDynamicallyScalable;
+    }
+
+    public void setDynamicallyScalable(Boolean dynamicallyScalable) {
+        isDynamicallyScalable = dynamicallyScalable;
+    }
+
+    public Long getOsTypeId() {
+        return osTypeId;
+    }
 }
diff --git a/api/src/org/apache/cloudstack/api/response/VolumeResponse.java b/api/src/org/apache/cloudstack/api/response/VolumeResponse.java
index a934563..e25adf6 100644
--- a/api/src/org/apache/cloudstack/api/response/VolumeResponse.java
+++ b/api/src/org/apache/cloudstack/api/response/VolumeResponse.java
@@ -16,18 +16,17 @@
 // under the License.
 package org.apache.cloudstack.api.response;
 
-import java.util.Date;
-import java.util.LinkedHashSet;
-import java.util.Set;
-
+import com.cloud.serializer.Param;
+import com.cloud.storage.Volume;
+import com.google.gson.annotations.SerializedName;
 import org.apache.cloudstack.acl.RoleType;
 import org.apache.cloudstack.api.ApiConstants;
 import org.apache.cloudstack.api.BaseResponseWithTagInformation;
 import org.apache.cloudstack.api.EntityReference;
 
-import com.cloud.serializer.Param;
-import com.cloud.storage.Volume;
-import com.google.gson.annotations.SerializedName;
+import java.util.Date;
+import java.util.LinkedHashSet;
+import java.util.Set;
 
 @EntityReference(value = Volume.class)
 @SuppressWarnings("unused")
@@ -514,4 +513,140 @@
     public void setTags(Set<ResourceTagResponse> tags) {
         this.tags = tags;
     }
+
+    public String getName() {
+        return name;
+    }
+
+    public String getZoneId() {
+        return zoneId;
+    }
+
+    public String getZoneName() {
+        return zoneName;
+    }
+
+    public String getVolumeType() {
+        return volumeType;
+    }
+
+    public Long getDeviceId() {
+        return deviceId;
+    }
+
+    public String getVirtualMachineId() {
+        return virtualMachineId;
+    }
+
+    public String getVirtualMachineName() {
+        return virtualMachineName;
+    }
+
+    public String getVirtualMachineDisplayName() {
+        return virtualMachineDisplayName;
+    }
+
+    public String getVirtualMachineState() {
+        return virtualMachineState;
+    }
+
+    public String getProvisioningType() {
+        return provisioningType;
+    }
+
+    public Long getSize() {
+        return size;
+    }
+
+    public Long getMinIops() {
+        return minIops;
+    }
+
+    public Long getMaxIops() {
+        return maxIops;
+    }
+
+    public Date getCreated() {
+        return created;
+    }
+
+    public String getState() {
+        return state;
+    }
+
+    public String getAccountName() {
+        return accountName;
+    }
+
+    public String getProjectId() {
+        return projectId;
+    }
+
+    public String getProjectName() {
+        return projectName;
+    }
+
+    public String getDomainId() {
+        return domainId;
+    }
+
+    public String getDomainName() {
+        return domainName;
+    }
+
+    public String getStorageType() {
+        return storageType;
+    }
+
+    public String getHypervisor() {
+        return hypervisor;
+    }
+
+    public String getDiskOfferingId() {
+        return diskOfferingId;
+    }
+
+    public String getDiskOfferingName() {
+        return diskOfferingName;
+    }
+
+    public String getDiskOfferingDisplayText() {
+        return diskOfferingDisplayText;
+    }
+
+    public String getStoragePoolName() {
+        return storagePoolName;
+    }
+
+    public String getSnapshotId() {
+        return snapshotId;
+    }
+
+    public Date getAttached() {
+        return attached;
+    }
+
+    public String getServiceOfferingId() {
+        return serviceOfferingId;
+    }
+
+    public String getServiceOfferingName() {
+        return serviceOfferingName;
+    }
+
+    public String getServiceOfferingDisplayText() {
+        return serviceOfferingDisplayText;
+    }
+
+    public Boolean getExtractable() {
+        return extractable;
+    }
+
+    public String getStatus() {
+        return status;
+    }
+
+    public Boolean getDisplayVolume() {
+        return displayVolume;
+    }
 }
diff --git a/api/src/org/apache/cloudstack/api/response/ZoneResponse.java b/api/src/org/apache/cloudstack/api/response/ZoneResponse.java
index 4266077..61bab02 100644
--- a/api/src/org/apache/cloudstack/api/response/ZoneResponse.java
+++ b/api/src/org/apache/cloudstack/api/response/ZoneResponse.java
@@ -239,4 +239,92 @@
         }
         this.resourceDetails = new HashMap<>(details);
     }
+
+    public String getId() {
+        return id;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public String getDns1() {
+        return dns1;
+    }
+
+    public String getDns2() {
+        return dns2;
+    }
+
+    public String getInternalDns1() {
+        return internalDns1;
+    }
+
+    public String getInternalDns2() {
+        return internalDns2;
+    }
+
+    public String getGuestCidrAddress() {
+        return guestCidrAddress;
+    }
+
+    public String getStatus() {
+        return status;
+    }
+
+    public String getDisplayText() {
+        return displayText;
+    }
+
+    public String getDomain() {
+        return domain;
+    }
+
+    public String getDomainId() {
+        return domainId;
+    }
+
+    public String getDomainName() {
+        return domainName;
+    }
+
+    public String getNetworkType() {
+        return networkType;
+    }
+
+    public boolean isSecurityGroupsEnabled() {
+        return securityGroupsEnabled;
+    }
+
+    public String getAllocationState() {
+        return allocationState;
+    }
+
+    public String getZoneToken() {
+        return zoneToken;
+    }
+
+    public String getDhcpProvider() {
+        return dhcpProvider;
+    }
+
+    public List<CapacityResponse> getCapacitites() {
+        return capacitites;
+    }
+
+    public boolean isLocalStorageEnabled() {
+        return localStorageEnabled;
+    }
+
+    public Set<ResourceTagResponse> getTags() {
+        return tags;
+    }
+
+    public Map<String, String> getResourceDetails() {
+        return resourceDetails;
+    }
 }
diff --git a/client/WEB-INF/classes/resources/messages_de_DE.properties b/client/WEB-INF/classes/resources/messages_de_DE.properties
index 30d1811..d850ab7 100644
--- a/client/WEB-INF/classes/resources/messages_de_DE.properties
+++ b/client/WEB-INF/classes/resources/messages_de_DE.properties
@@ -335,6 +335,7 @@
 label.add.private.gateway=Privaten Gateway hinzuf\u00fcgen
 label.add.region=Region hinzuf\u00fcgen
 label.add.resources=Ressourcen hinzuf\u00fcgen
+label.add.role=Rolle hinzuf\u00fcgen
 label.add.route=Route hinzuf\u00fcgen
 label.add.rule=Regel hinzuf\u00fcgen
 label.add.secondary.storage=Sekund\u00e4rspeicher hinzuf\u00fcgen
@@ -574,6 +575,7 @@
 label.delete.portable.ip.range=Portablen IP-Bereich l\u00f6schen
 label.delete.profile=Profil l\u00f6schen
 label.delete.project=Projekt l\u00f6schen
+label.delete.role=Rolle l\u00f6schen
 label.delete.secondary.staging.store=Sekund\u00e4rer Staging Store l\u00f6schen
 label.delete.SRX=SRX l\u00f6schen
 label.delete.ucs.manager=UCS Manager l\u00f6schen
@@ -658,6 +660,7 @@
 label.edit.network.details=Netzwerkdetails bearbeiten
 label.edit.project.details=Projektdetails bearbeiten
 label.edit.region=Region bearbeiten
+label.edit.role=Rolle bearbeiten
 label.edit.rule=Regel bearbeiten
 label.edit.secondary.ips=Sekund\u00e4re IPs bearbeiten
 label.edit.tags=Schlagw\u00f6rter bearbeiten
@@ -779,7 +782,7 @@
 label.hide.ingress.rule=Verstecke Regeln, die den Zutritt steuern
 label.hints=Hinweise
 label.home=Start
-label.host.alerts=Host-Alarme
+label.host.alerts=Hosts im Alarmzustand
 label.host=Host
 label.host.MAC=Host-MAC
 label.host.name=Host Name
@@ -1039,6 +1042,7 @@
 label.metrics.network.usage=Netzwerk Nutzung
 label.metrics.network.write=Schreiben
 label.metrics.num.cpu.cores=Cores
+label.metrics.outofbandmanagementpowerstate=Betriebszustand
 label.metrics.property=Eigentum
 label.metrics.scope=Geltungsbereich
 label.metrics.state=Status
@@ -1161,8 +1165,17 @@
 label.os.type=OS Typ
 label.other=Andere
 label.outofbandmanagement.action=Aktion
+label.outofbandmanagement.action.issue=Eine Out-of-band Verwaltungs-Strom Aktion durchf\u00fchren
+label.outofbandmanagement.address=Adresse
+label.outofbandmanagement.changepassword=Passwort f\u00fcr Out-of-band Verwaltung \u00e4ndern
+label.outofbandmanagement.configure=Out-of-band Verwaltung konfigurieren
+label.outofbandmanagement.disable=Out-of-band Verwaltung deaktivieren
+label.outofbandmanagement.driver=Treiber
+label.outofbandmanagement.enable=Out-of-band Verwaltung aktivieren
+label.outofbandmanagement=Out-of-band Verwaltung
 label.outofbandmanagement.password=Passwort
 label.outofbandmanagement.port=Port
+label.outofbandmanagement.reenterpassword=Passwort erneut eingeben
 label.outofbandmanagement.username=Benutzername
 label.override.guest.traffic=Gast-Datenverkehr \u00fcberschreiben
 label.override.public.traffic=\u00d6ffentlichen Datenverkehr \u00fcberschreiben
@@ -1187,6 +1200,7 @@
 label.path=Pfad
 label.PA.threat.profile=Palo Alto Threat Profil
 label.perfect.forward.secrecy=Perfect Forward Secrecy
+label.permission=Berechtigung
 label.persistent=Persistent
 label.physical.network.ID=Physikalisches Netzwerkkennung
 label.physical.network.name=Name des physischen Netzwerks
@@ -1215,6 +1229,7 @@
 label.port.forwarding=Portweiterleitung
 label.port=Port
 label.port.range=Portbereich
+label.powerstate=Betriebszustand
 label.PreSetup=Voreinstellung
 label.previous=Vorherige
 label.prev=Vor
@@ -1384,6 +1399,8 @@
 label.review=Nachpr\u00fcfung
 label.revoke.project.invite=Einladung widerrufen
 label.role=Rolle
+label.roles=Rollen
+label.roletype=Rollentyp
 label.root.certificate=Root-Zertifikat
 label.root.disk.controller=Root-Festplatten-Controller
 label.root.disk.offering=Root-Festplattenangebot
@@ -1392,6 +1409,7 @@
 label.routing.host=Routing Host
 label.routing=Routing
 label.rule.number=Regelnummer
+label.rule=Regel
 label.rules=Regeln
 label.running.vms=Laufende VMs
 label.s3.access_key=Zugriffsschl\u00fcssel
@@ -2110,6 +2128,12 @@
 message.number.pods=<h2><span>Anzahl der</span>Pods</h2>
 message.number.storage=<h2><span> \# von </span> Hauptspeichervolumina</h2>
 message.number.zones=<h2><span> \# of </span> Zonen</h2>
+message.outofbandmanagement.action.maintenance=Warnung Host ist im Wartungsmodus
+message.outofbandmanagement.changepassword=Passwort f\u00fcr Out-of-band Verwaltung \u00e4ndern
+message.outofbandmanagement.configure=Out-of-band Verwaltung konfigurieren
+message.outofbandmanagement.disable=Out-of-band Verwaltung deaktivieren
+message.outofbandmanagement.enable=Out-of-band Verwaltung aktivieren
+message.outofbandmanagement.issue=Eine Out-of-band Verwaltungs-Strom Aktion durchf\u00fchren
 message.password.has.been.reset.to=Passwort wurde zur\u00fcckgesetzt auf
 message.password.of.the.vm.has.been.reset.to=Passwort der VM wurde zur\u00fcckgesetzt auf
 message.pending.projects.1=Sie haben ausstehende Projekteinladungen\:
@@ -2146,6 +2170,7 @@
 message.restart.vpc=Bitte best\u00e4tigen Sie, dass Sie den VPC neu starten m\u00f6chten
 message.restart.vpc.remark=Bitte best\u00e4tigen Sie, dass Sie die VPC neu starten m\u00f6chten <p>small><i>Hinweis\: Ein nicht-redundante VPC redundant zu machen wird eine Bereinigung erzwingen. Die Netzwerke werden dadurch einige Minuten nicht verf\u00fcgbar sein</i>.</small></p>
 message.restoreVM=M\u00f6chten Sie die VM wiederherstellen?
+message.role.ordering.fail=Die Neuordnung der Regelberechtigungen wurde abgebrochen, es sind \u00c4nderungen eingetreten, w\u00e4hrend Sie an der Liste Arbeiten durchgef\u00fchrt haben. Bitte versuchen Sie es erneut.
 message.security.group.usage=(Verwenden Sie <strong>Ctrl-click</strong> um alle passenden Sicherheits Gruppen auszuw\u00e4hlen)
 message.select.affinity.groups=Bitte w\u00e4hlen Sie beliebige Affinit\u00e4tsgruppen, zu denen diese VM geh\u00f6ren soll\:
 message.select.a.zone=Eine Zone steht typischerweise f\u00fcr ein einzelnes Rechenzentrum. Mehrere Zonen helfen dabei, die Cloud zuverl\u00e4ssiger zu machen durch physikalische Isolation und Redundanz.
diff --git a/client/WEB-INF/classes/resources/messages_es.properties b/client/WEB-INF/classes/resources/messages_es.properties
index 8150845..bcb8ed5 100644
--- a/client/WEB-INF/classes/resources/messages_es.properties
+++ b/client/WEB-INF/classes/resources/messages_es.properties
@@ -335,6 +335,7 @@
 label.add.private.gateway=Agregar Gateway Privado
 label.add.region=Agregar Regi\u00f3n
 label.add.resources=Agregar Recursos
+label.add.role=Agregar Rol
 label.add.route=Agregar ruta
 label.add.rule=Agregar regla
 label.add.secondary.storage=A\u00f1adir secundaria almacenamiento
@@ -574,6 +575,7 @@
 label.delete.portable.ip.range=Borrar Rango IP Port\u00e1til
 label.delete.profile=Borrar Perfil
 label.delete.project=Eliminar proyecto
+label.delete.role=Borrar Rol
 label.delete.secondary.staging.store=Borrar Almacenamiento Secundario Temporario
 label.delete.SRX=Borrar SRX
 label.delete.ucs.manager=Borrar UCS Manager
@@ -658,6 +660,7 @@
 label.edit.network.details=Editar detalles de red
 label.edit.project.details=Editar detalles de proyecto
 label.edit.region=Editar Regi\u00f3n
+label.edit.role=Editar Rol
 label.edit.rule=Editar regla
 label.edit.secondary.ips=Editar IPs secundarios
 label.edit.tags=Editar etiquetas
@@ -779,7 +782,7 @@
 label.hide.ingress.rule=Ocultar el art\u00edculo ingreso
 label.hints=Sugerencias
 label.home=Inicio
-label.host.alerts=Host Alertas
+label.host.alerts=Servidores en Estado de Alerta
 label.host=Ej\u00e9rcitos
 label.host.MAC=MAC del Host
 label.host.name=nombre de host
@@ -1039,6 +1042,7 @@
 label.metrics.network.usage=Uso de la Red
 label.metrics.network.write=Escritura
 label.metrics.num.cpu.cores=Cores
+label.metrics.outofbandmanagementpowerstate=Estado de la Alimentaci\u00f3n
 label.metrics.property=Propiedad
 label.metrics.scope=Alcance
 label.metrics.state=Estado
@@ -1161,8 +1165,17 @@
 label.os.type=tipo de Sistema Operativo
 label.other=Otro
 label.outofbandmanagement.action=Acci\u00f3n
+label.outofbandmanagement.action.issue=Enviar Acci\u00f3n de Gesti\u00f3n de Alimentac\u00edon Fuera-de-Banda
+label.outofbandmanagement.address=Direcci\u00f3n
+label.outofbandmanagement.changepassword=Cambiar la contrase\u00f1a de la gesti\u00f3n Out-of-band
+label.outofbandmanagement.configure=Configurar Gesti\u00f3n Out-of-band
+label.outofbandmanagement.disable=Deshabilitar Gesti\u00f3n Out-of-band
+label.outofbandmanagement.driver=Driver
+label.outofbandmanagement.enable=Habilitar Gesti\u00f3n Out-of-band
+label.outofbandmanagement=Gesti\u00f3n Out-of-band
 label.outofbandmanagement.password=Contrase\u00f1a
 label.outofbandmanagement.port=Puerto
+label.outofbandmanagement.reenterpassword=Reingresar contrase\u00f1a
 label.outofbandmanagement.username=Nombre de usuario
 label.override.guest.traffic=Sobreescribir Tr\u00e1fico Guest
 label.override.public.traffic=Sobreescribir Tr\u00e1fico Public
@@ -1187,6 +1200,7 @@
 label.PA.threat.profile=Perf\u00edl de Amenazas Palo Alto
 label.path=Ruta
 label.perfect.forward.secrecy=Perfect Forward Secrecy
+label.permission=Autorizaciones
 label.persistent=Persistente
 label.physical.network.ID=ID de red f\u00edsica
 label.physical.network.name=Nombre de red f\u00edsica
@@ -1215,6 +1229,7 @@
 label.port.forwarding=Port Forwarding
 label.port=Puerto
 label.port.range=rango de puertos
+label.powerstate=Estado de la Alimentaci\u00f3n
 label.PreSetup=PreSetup
 label.prev=Anterior
 label.previous=Previo
@@ -1384,6 +1399,8 @@
 label.review=Revisar
 label.revoke.project.invite=Cancelar Invitaci\u00f3n
 label.role=Papel
+label.roles=Roles
+label.roletype=Tipo de Rol
 label.root.certificate=Certificado Ra\u00edz
 label.root.disk.controller=Controladora de disco ROOT
 label.root.disk.offering=Root Disco Offering
@@ -1392,6 +1409,7 @@
 label.routing=Enrutamiento
 label.routing.host=Servidor de Routeo
 label.rule.number=N\u00famero de Regla
+label.rule=Regla
 label.rules=Reglas
 label.running.vms=Ejecuci\u00f3n de m\u00e1quinas virtuales
 label.s3.access_key=Llave de Acceso
@@ -2049,7 +2067,7 @@
 message.installWizard.copy.whatIsAHost=Un servidor es una sola computadora. Los Servidores proveen los recursos de computo necesarios para ejecutar las m\u00e1quinas virtuales. Cada servidor tiene un hipervisor instalado para gestionar las VMs guest (excepto en los servidores baremetal, los cuales son un caso especial que se explaya en la Gu\u00eda de Administraci\u00f3n Avanzada). Por ejemplo, un servidor Linux con KVM habilitado, un servidor con Citrix XenServer o un servidor con ESXi. En una instalaci\u00f3n Basica, usaremos un solo servidor ejecutando XenServer o KVM. <br/><br/>El servidor es la m\u00ednima unidad organizacional de CloudStack&\#8482; .Los servidores est\u00e1n contenidos dentro de los ilustres, los ilustres en los pods, y estos \u00faltimos en las zonas.
 message.installWizard.copy.whatIsAPod=Un pod representa generalmente un solo rock. Los servidores en el mismo por estar en la misma subred.<br/><br/>El por es la segunda agrupaci\u00f3n organizacional dentro de CloudStack&\#8482; .Los Pods est\u00e1n contenidos dentro de la zona. Cada zona puede contener uno m\u00e1s pods. En la instalaci\u00f3n B\u00e1sica, solo se necesita tener un por en la zona.
 message.installWizard.copy.whatIsAZone=Una zona es la unidad organizacional m\u00e1s grande dentro de una instalaci\u00f3n de CloudStack&\#8482;. Una zona tipicamente se corresponde a un solo datacenter, sin embargo esta permitido contar con varias zonas dentro del mismo datacenter. El beneficio de organizar la infraestructura en zonas es que provee aislaci\u00f3n f\u00edsica y redundancia. Por ejemplo, cada zona puede tener su propia fuente de alimentaci\u00f3n y lo mismo con su salida de red, ademas de poder estar separadas geograficamente en grandes distancias (lo cual no es obligatorio).
-message.installWizard.copy.whatIsCloudStack=CloudStack&\#8482 es una plataforma de software que aglutina recursos computo para poder crear coludas de infraestructuras como Servicio (IaaS), tanto p\u00fablicas como privadas.\nCloudStack&\#8482 gestiona la red, el almacenamiento y los nodos de computo que conforma la infraestructura de cloud. Se puede usar CloudStack&\#8482 para desplegar, gestionar y configurar ambientes de cloud computan.<br/><br/> Extendiendose m\u00e1s all\u00e1 del manejo individual de m\u00e1quinas virtuales en hardware comotidizado, CloudStack&\#8482 provee una soluci\u00f3n llave en mano de un software de infraestructura de red para ofrecer datacenter virtuales como servicio, proveyendo todos los componentes esenciales para construir, desplegar y gestionar aplicaciones cloud multi-tier y multi-tenant. Se ofrecen dos versiones, la open source y la Premium, brindando la primera caracter\u00edsticas casi id\u00e9nticas.
+message.installWizard.copy.whatIsCloudStack=CloudStack&\#8482 es una plataforma de software que aglutina recursos computo para poder crear coludas de infraestructuras como Servicio (IaaS), tanto p\u00fablicas como privadas.<br/><br/> CloudStack&\#8482 gestiona la red, el almacenamiento y los nodos de computo que conforma la infraestructura de cloud. Se puede usar CloudStack&\#8482 para desplegar, gestionar y configurar ambientes de cloud computan.<br/><br/> Extendiendose m\u00e1s all\u00e1 del manejo individual de m\u00e1quinas virtuales en hardware comotidizado, CloudStack&\#8482 provee una soluci\u00f3n llave en mano de un software de infraestructura de red para ofrecer datacenter virtuales como servicio, proveyendo todos los componentes esenciales para construir, desplegar y gestionar aplicaciones cloud multi-tier y multi-tenant. Se ofrecen dos versiones, la open source y la Premium, brindando la primera caracter\u00edsticas casi id\u00e9nticas.
 message.installWizard.copy.whatIsPrimaryStorage=La infraestrucutra cloud de CloudStack&\#8482 hace uso de dos tipos de almacenamiento, el primario y el secundario. Ambos pueden ser iSCSI, NFS o discos locales. <br/><br/>El <strong>Almacenamiento Primario</strong> se asocia a un cluster, y almacena los vol\u00famenes de discos de cada VM para todas las VMs en los servidores del cluster. El almacenamiento primario es t\u00edpicamente alojado cerca de los servidores.
 message.installWizard.copy.whatIsSecondaryStorage=El almacenamiento secundario est\u00e1 asociado a una zona, y almacena lo siguiente\: <ul> <li> Plantillas - im\u00e1genes del sistema operativo que se pueden utilizar para arrancar VMs, pueden incluir informaci\u00f3n de configuraci\u00f3n adicional, como las aplicaciones instaladas </li><li>Im\u00e1genes ISO - im\u00e1genes del Sistema Operativo que pueden ser boteables o no boteables </li><li>Disco instant\u00e1neas de vol\u00famenes  - copias de datos guardadas de VM que se pueden utilizar para la recuperaci\u00f3n de datos o para crear nuevas plantillas</ul>
 message.installWizard.now.building=Ahora construyendo su nube...
@@ -2110,6 +2128,12 @@
 message.number.pods=<h2> <span> \# de </span> Las vainas </h2>
 message.number.storage=<h2> <span> \# de </span> Almacenamiento primario </h2>
 message.number.zones=<h2> <span> \# de </span> Zonas </h2>
+message.outofbandmanagement.action.maintenance=Atenci\u00f3n, el Servidor est\u00e1 en modo mantenimiento
+message.outofbandmanagement.changepassword=Cambiar contrase\u00f1a de Gesti\u00f3n Out-of-band
+message.outofbandmanagement.configure=Configurar Gesti\u00f3n Out-of-band
+message.outofbandmanagement.disable=Deshabilitar gesti\u00f3n Out-of-band
+message.outofbandmanagement.enable=Habilitar gesti\u00f3n Out-of-band
+message.outofbandmanagement.issue=Enviar Acci\u00f3n de Gesti\u00f3n de Alimentac\u00edon Fuera-de-Banda
 message.password.has.been.reset.to=La Contrase\u00f1a se ha cambiado a
 message.password.of.the.vm.has.been.reset.to=La Contrase\u00f1a se ha cambiado a
 message.pending.projects.1=Tiene invitaciones a proyectos pendientes\:
@@ -2146,6 +2170,7 @@
 message.restart.vpc=Por favor confirme que usted quiere reiniciar el VPC
 message.restart.vpc.remark=Por favor confirme que desea reiniciar el VPC <p><small><i>Atenci\u00f3n\: creando un VPC sin redundancia forzara la limpieza. Todas las redes dejaran de estar disponibles por unos minutos</i>.</small></p>
 message.restoreVM=\u00bfDesea recuperar la VM?
+message.role.ordering.fail=Reordenaci\u00f3n de permisos de reglas abortada ya que la lista ha cambiado mientras realizaba los cambios. Por favor, intente de nuevo. 
 message.security.group.usage=(Uso <strong> pulse Ctrl </strong> para seleccionar todos los grupos de seguridad se aplica)
 message.select.affinity.groups=Por favor elija los grupos de afinidad a los que desea unir la VM\:
 message.select.a.zone=Una zona normalmente se corresponde con un solo datacenter. M\u00faltiples zonas pueden ayudar a aumentar la disponibilidad del cloud al proveer aislaci\u00f3n f\u00edsica y redundancia.
diff --git a/client/WEB-INF/classes/resources/messages_fr_FR.properties b/client/WEB-INF/classes/resources/messages_fr_FR.properties
index 4dc9082..32b5f35 100644
--- a/client/WEB-INF/classes/resources/messages_fr_FR.properties
+++ b/client/WEB-INF/classes/resources/messages_fr_FR.properties
@@ -33,7 +33,7 @@
 error.unresolved.internet.name=Votre nom Internet ne peut pas \u00eatre r\u00e9solu.
 force.delete.domain.warning=Attention \: Choisir cette option entra\u00eenera la suppression de tous les domaines issus et l\\'ensemble des comptes associ\u00e9s, ainsi que de leur ressources
 force.delete=Forcer la suppression
-force.remove.host.warning=Attention \: Choisir cette option entra\u00eenera CloudStack \u00e0\u00a0forecer l\\'arr\u00eat de l\\'ensemble des machines virtuelles avant d\\'enlever l\\'h\u00f4te du cluster
+force.remove.host.warning=Attention \: Choisir cette option entra\u00eenera CloudStack \u00e0 forcer l\\'arr\u00eat de l\\'ensemble des machines virtuelles avant d\\'enlever cet h\u00f4te du cluster
 force.remove=Suppression forc\u00e9e
 force.stop=Forcer l\\'arr\u00eat
 force.stop.instance.warning=Attention \: un arr\u00eat forc\u00e9 sur cette instance est la dernier option. Cela peut engendrer des pertes de donn\u00e9es et/ou un comportement inconsistant de votre instance.
@@ -782,7 +782,7 @@
 label.hide.ingress.rule=Cacher la r\u00e8gle d\\'entr\u00e9e
 label.hints=Astuces
 label.home=Accueil
-label.host.alerts=Alertes des h\u00f4tes
+label.host.alerts=H\u00f4tes en \u00e9tat d\\'Alerte
 label.host=H\u00f4te
 label.host.MAC=Adresse MAC h\u00f4te
 label.host.name=Nom d\\'h\u00f4te
@@ -1175,6 +1175,7 @@
 label.outofbandmanagement=Gestion flux administration
 label.outofbandmanagement.password=Mot de passe
 label.outofbandmanagement.port=Port
+label.outofbandmanagement.reenterpassword=Re-saisir Mot de passe
 label.outofbandmanagement.username=Identifiant
 label.override.guest.traffic=Remplacer Trafic-invit\u00e9
 label.override.public.traffic=Remplacer Trafic-public
diff --git a/client/WEB-INF/classes/resources/messages_hu.properties b/client/WEB-INF/classes/resources/messages_hu.properties
index 3386f03..7497b8f 100644
--- a/client/WEB-INF/classes/resources/messages_hu.properties
+++ b/client/WEB-INF/classes/resources/messages_hu.properties
@@ -771,7 +771,6 @@
 label.hide.ingress.rule=Ingress szab\u00e1ly rejt\u00e9se
 label.hints=Tippek
 label.home=Kezd\u0151lap
-label.host.alerts=Kiszolg\u00e1l\u00f3 riaszt\u00e1sok
 label.host=Kiszolg\u00e1l\u00f3
 label.host.MAC=Kiszolg\u00e1l\u00f3 MAC
 label.host.name=Kiszolg\u00e1l\u00f3 n\u00e9v
diff --git a/client/WEB-INF/classes/resources/messages_ja_JP.properties b/client/WEB-INF/classes/resources/messages_ja_JP.properties
index 2ed3ce6..89766e8 100644
--- a/client/WEB-INF/classes/resources/messages_ja_JP.properties
+++ b/client/WEB-INF/classes/resources/messages_ja_JP.properties
@@ -779,7 +779,6 @@
 label.hide.ingress.rule=\u53d7\u4fe1\u898f\u5247\u3092\u96a0\u3059
 label.hints=\u30d2\u30f3\u30c8
 label.home=\u30db\u30fc\u30e0
-label.host.alerts=\u30db\u30b9\u30c8 \u30a2\u30e9\u30fc\u30c8
 label.host.MAC=\u30db\u30b9\u30c8\u306e MAC
 label.host.name=\u30db\u30b9\u30c8\u540d
 label.hosts=\u30db\u30b9\u30c8
diff --git a/client/WEB-INF/classes/resources/messages_ko_KR.properties b/client/WEB-INF/classes/resources/messages_ko_KR.properties
index f7bebd6..28d1ecb 100644
--- a/client/WEB-INF/classes/resources/messages_ko_KR.properties
+++ b/client/WEB-INF/classes/resources/messages_ko_KR.properties
@@ -18,6 +18,7 @@
 changed.item.properties=\ud56d\ubaa9 \uc18d\uc131 \ubcc0\uacbd
 confirm.enable.s3=S3 \uae30\ubc18 2\ucc28 \uc800\uc7a5\uc18c \uc9c0\uc6d0\uc744 \ud558\ub824\uba74 \uc544\ub798 \uc815\ubcf4\ub97c \uc785\ub825\ud574 \uc8fc\uc2ed\uc2dc\uc624.
 confirm.enable.swift=Swift \uae30\uc220 \uc9c0\uc6d0\ub97c \uc0ac\uc6a9 \ud558\ub824\uba74 \ub2e4\uc74c \uc815\ubcf4\ub97c \uc785\ub825\ud574 \uc8fc\uc2ed\uc2dc\uc624.
+error.could.not.change.your.password.because.ldap.is.enabled=LDAP \uae30\ub2a5\uc774 \ud65c\uc131\ud654 \ub418\uc5b4 \uc788\uae30 \ub54c\ubb38\uc5d0 \ud328\uc2a4\uc6cc\ub4dc \ubcc0\uacbd\uc744 \uc2e4\ud328\ud558\uc600\uc2b5\ub2c8\ub2e4.
 error.could.not.enable.zone=Zone\uc744 \uc0ac\uc6a9 \ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4.
 error.installWizard.message=\ubb38\uc81c\uac00 \ubc1c\uc0dd\ud588\uc2b5\ub2c8\ub2e4. \ub2e4\uc2dc \uc624\ub958\ub97c \uc218\uc815\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.
 error.invalid.username.password=\uc720\ud6a8\ud558\uc9c0 \uc54a\uc740 \uc0ac\uc6a9\uc790\uba85 \ub610\ub294 \uc554\ud638
@@ -541,7 +542,6 @@
 label.help=\ub3c4\uc6c0\ub9d0
 label.hide.ingress.rule=\uc218\uc2e0 \uaddc\uce59\uc744 \uc228\uae30\uae30
 label.hints=\uc815\ubcf4
-label.host.alerts=\ud638\uc2a4\ud2b8 \uc54c\ub9bc \uccb4\uacc4
 label.host.MAC=\ud638\uc2a4\ud2b8 MAC
 label.host.name=\ud638\uc2a4\ud2b8\uba85
 label.hosts=\ud638\uc2a4\ud2b8
@@ -868,6 +868,7 @@
 label.quota.state=\uc0c1\ud0dc
 label.reboot=\uc7ac\uc2dc\uc791
 label.recent.errors=\ucd5c\uadfc \uc624\ub958
+label.recover.vm=VM \ubcf5\uad6c
 label.redundant.router.capability=\uc911\ubcf5 \ub77c\uc6b0\ud130 \uae30\ub2a5
 label.redundant.router=\uc911\ubcf5 \ub77c\uc6b0\ud130
 label.redundant.state=\uc911\ubcf5 \uc0c1\ud0dc
diff --git a/client/WEB-INF/classes/resources/messages_nb_NO.properties b/client/WEB-INF/classes/resources/messages_nb_NO.properties
index d3117c0..cec91dc 100644
--- a/client/WEB-INF/classes/resources/messages_nb_NO.properties
+++ b/client/WEB-INF/classes/resources/messages_nb_NO.properties
@@ -779,7 +779,6 @@
 label.hide.ingress.rule=Skjul ingressregel
 label.hints=Hint
 label.home=Hjem
-label.host.alerts=Vertsvarsler
 label.host.MAC=Verts MAC
 label.host.name=Vertsnavn
 label.hosts=Verter
diff --git a/client/WEB-INF/classes/resources/messages_nl_NL.properties b/client/WEB-INF/classes/resources/messages_nl_NL.properties
index a1e1347..b691eaa 100644
--- a/client/WEB-INF/classes/resources/messages_nl_NL.properties
+++ b/client/WEB-INF/classes/resources/messages_nl_NL.properties
@@ -779,7 +779,6 @@
 label.hide.ingress.rule=Verberg Inkomende Regel
 label.hints=Tips
 label.home=Home
-label.host.alerts=Host Waarschuwingen
 label.host=Host
 label.host.MAC=Host MAC
 label.host.name=Hostnaam
diff --git a/client/WEB-INF/classes/resources/messages_pt_BR.properties b/client/WEB-INF/classes/resources/messages_pt_BR.properties
index 2ad2760..b64cea3 100644
--- a/client/WEB-INF/classes/resources/messages_pt_BR.properties
+++ b/client/WEB-INF/classes/resources/messages_pt_BR.properties
@@ -779,7 +779,6 @@
 label.hide.ingress.rule=Ocultar Regra de Entrada
 label.hints=Dicas
 label.home=Home
-label.host.alerts=Alertas de Host
 label.host=Host
 label.host.MAC=Host MAC
 label.host.name=Host Name
@@ -1161,6 +1160,7 @@
 label.os.type=Tipo de SO
 label.other=Outro
 label.outofbandmanagement.action=A\u00e7\u00e3o
+label.outofbandmanagement.address=Endere\u00e7o
 label.outofbandmanagement.password=Senha
 label.outofbandmanagement.port=Porta
 label.outofbandmanagement.username=Nome de usu\u00e1rio
@@ -1187,6 +1187,7 @@
 label.path=Caminho (Path)
 label.PA.threat.profile=Palo Alto Threat Profile
 label.perfect.forward.secrecy=Perfect Forward Secrecy
+label.permission=Permiss\u00e3o
 label.persistent=Persistente
 label.physical.network.ID=ID da rede f\u00edsica
 label.physical.network.name=Nome da rede f\u00edsica
@@ -1392,6 +1393,7 @@
 label.routing.host=Host de Roteamento
 label.routing=Roteamento
 label.rule.number=Regra N\u00famero
+label.rule=Regra
 label.rules=Regras
 label.running.vms=VMs Rodando
 label.s3.access_key=Chave de acesso
diff --git a/client/WEB-INF/classes/resources/messages_ru_RU.properties b/client/WEB-INF/classes/resources/messages_ru_RU.properties
index 2225fad..05fe718 100644
--- a/client/WEB-INF/classes/resources/messages_ru_RU.properties
+++ b/client/WEB-INF/classes/resources/messages_ru_RU.properties
@@ -610,7 +610,6 @@
 label.hide.ingress.rule=\u0421\u043a\u0440\u044b\u0442\u044c \u0432\u0445\u043e\u0434\u044f\u0449\u0435\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u043e
 label.hints=\u041f\u043e\u0434\u0441\u043a\u0430\u0437\u043a\u0438
 label.home=\u0413\u043b\u0430\u0432\u043d\u0430\u044f
-label.host.alerts=\u041e\u043f\u043e\u0432\u0435\u0449\u0435\u043d\u0438\u044f \u0443\u0437\u043b\u0430
 label.host.MAC=MAC \u0443\u0437\u043b\u0430
 label.host.name=\u0418\u043c\u044f \u0443\u0437\u043b\u0430
 label.hosts=\u0423\u0437\u043b\u044b
diff --git a/client/WEB-INF/classes/resources/messages_zh_CN.properties b/client/WEB-INF/classes/resources/messages_zh_CN.properties
index 11530f9..7b2419b 100644
--- a/client/WEB-INF/classes/resources/messages_zh_CN.properties
+++ b/client/WEB-INF/classes/resources/messages_zh_CN.properties
@@ -778,7 +778,6 @@
 label.hide.ingress.rule=\u9690\u85cf\u5165\u53e3\u89c4\u5219
 label.hints=\u63d0\u793a
 label.home=\u9996\u9875
-label.host.alerts=\u4e3b\u673a\u8b66\u62a5
 label.host.MAC=\u4e3b\u673a MAC
 label.host.name=\u4e3b\u673a\u540d\u79f0
 label.hosts=\u4e3b\u673a
diff --git a/client/pom.xml b/client/pom.xml
index 9b4d4b5..1f246ff 100644
--- a/client/pom.xml
+++ b/client/pom.xml
@@ -17,7 +17,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
   </parent>
 
   <dependencies>
@@ -103,6 +103,11 @@
     </dependency>
     <dependency>
       <groupId>org.apache.cloudstack</groupId>
+      <artifactId>cloud-plugin-metrics</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.cloudstack</groupId>
       <artifactId>cloud-plugin-network-nvp</artifactId>
       <version>${project.version}</version>
     </dependency>
diff --git a/client/tomcatconf/db.properties.in b/client/tomcatconf/db.properties.in
index 1c2b55f..ab7d7c90 100644
--- a/client/tomcatconf/db.properties.in
+++ b/client/tomcatconf/db.properties.in
@@ -39,7 +39,7 @@
 db.cloud.timeBetweenEvictionRunsMillis=40000
 db.cloud.minEvictableIdleTimeMillis=240000
 db.cloud.poolPreparedStatements=false
-db.cloud.url.params=prepStmtCacheSize=517&cachePrepStmts=true
+db.cloud.url.params=prepStmtCacheSize=517&cachePrepStmts=true&sessionVariables=sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'
 
 # CloudStack database SSL settings
 db.cloud.useSSL=false
diff --git a/core/pom.xml b/core/pom.xml
index dfb566f..3a9b61e 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -25,7 +25,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
   </parent>
   <dependencies>
     <dependency>
diff --git a/core/src/com/cloud/agent/api/SetHostParamsCommand.java b/core/src/com/cloud/agent/api/SetHostParamsCommand.java
new file mode 100644
index 0000000..9f13bf5
--- /dev/null
+++ b/core/src/com/cloud/agent/api/SetHostParamsCommand.java
@@ -0,0 +1,43 @@
+//
+// 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;
+
+import java.util.Map;
+
+public class SetHostParamsCommand extends Command {
+
+    Map<String, String> params;
+
+    public SetHostParamsCommand(Map<String, String> params) {
+        this.params = params;
+    }
+
+    public Map<String, String> getParams() {
+        return params;
+    }
+
+    protected SetHostParamsCommand() {
+    }
+
+    @Override
+    public boolean executeInSequence() {
+        return true;
+    }
+}
diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java b/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java
index 87a38d3..96dea5d 100644
--- a/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java
+++ b/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java
@@ -75,6 +75,7 @@
     private int _retry;
     private int _port;
     private Duration _eachTimeout;
+    private Map<String, Object> _params;
 
     private String _cfgVersion = "1.0";
 
@@ -259,8 +260,18 @@
         return new GetDomRVersionAnswer(cmd, result.getDetails(), lines[0], lines[1]);
     }
 
+    public boolean configureHostParams(final Map<String, String> params) {
+        if (_params.get("router.aggregation.command.each.timeout") == null) {
+            String value = (String)params.get("router.aggregation.command.each.timeout");
+            _eachTimeout = Duration.standardSeconds(NumbersUtil.parseInt(value, 10));
+        }
+
+        return true;
+    }
+
     public boolean configure(final String name, final Map<String, Object> params) throws ConfigurationException {
         _name = name;
+        _params = params;
 
         String value = (String)params.get("ssh.sleep");
         _sleep = NumbersUtil.parseInt(value, 10) * 1000;
diff --git a/debian/changelog b/debian/changelog
index 19d3500..219ba69 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,15 @@
+cloudstack (4.9.3.0-SNAPSHOT) unstable; urgency=low
+
+  * Update the version to 4.9.3.0-SNAPSHOT
+
+ -- the Apache CloudStack project <dev@cloudstack.apache.org>  Fri, 06 Dec 2016 10:38:00 +0530
+
+cloudstack (4.9.2.0) unstable; urgency=low
+
+  * Update the version to 4.9.2.0
+
+ -- the Apache CloudStack project <dev@cloudstack.apache.org>  Tue, 03 Jan 2017 12:28:47 +0530
+
 cloudstack (4.9.2.0-SNAPSHOT) unstable; urgency=low
 
   * Update the version to 4.9.2.0-SNAPSHOT
diff --git a/developer/pom.xml b/developer/pom.xml
index 1f2a866..6a11e56 100644
--- a/developer/pom.xml
+++ b/developer/pom.xml
@@ -18,7 +18,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
   </parent>
   <dependencies>
     <dependency>
diff --git a/engine/api/pom.xml b/engine/api/pom.xml
index 1921d16..3d32b08 100644
--- a/engine/api/pom.xml
+++ b/engine/api/pom.xml
@@ -16,7 +16,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloud-engine</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../pom.xml</relativePath>
   </parent>
   <dependencies>
diff --git a/engine/components-api/pom.xml b/engine/components-api/pom.xml
index ff2b3e2..888481f 100644
--- a/engine/components-api/pom.xml
+++ b/engine/components-api/pom.xml
@@ -24,7 +24,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloud-engine</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../pom.xml</relativePath>
   </parent>
   <dependencies>
diff --git a/engine/network/pom.xml b/engine/network/pom.xml
index 7752a4b..b51bb26 100644
--- a/engine/network/pom.xml
+++ b/engine/network/pom.xml
@@ -24,7 +24,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloud-engine</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../pom.xml</relativePath>
   </parent>
   <dependencies>
diff --git a/engine/orchestration/pom.xml b/engine/orchestration/pom.xml
index 3e29c2b..88e2e7d 100755
--- a/engine/orchestration/pom.xml
+++ b/engine/orchestration/pom.xml
@@ -24,7 +24,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloud-engine</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../pom.xml</relativePath>
   </parent>
   <dependencies>
diff --git a/engine/orchestration/src/com/cloud/agent/manager/AgentManagerImpl.java b/engine/orchestration/src/com/cloud/agent/manager/AgentManagerImpl.java
index aa7068a..ba90ede 100644
--- a/engine/orchestration/src/com/cloud/agent/manager/AgentManagerImpl.java
+++ b/engine/orchestration/src/com/cloud/agent/manager/AgentManagerImpl.java
@@ -61,6 +61,7 @@
 import com.cloud.agent.api.PingRoutingCommand;
 import com.cloud.agent.api.ReadyAnswer;
 import com.cloud.agent.api.ReadyCommand;
+import com.cloud.agent.api.SetHostParamsCommand;
 import com.cloud.agent.api.ShutdownCommand;
 import com.cloud.agent.api.StartupAnswer;
 import com.cloud.agent.api.StartupCommand;
@@ -214,6 +215,8 @@
 
         registerForHostEvents(new BehindOnPingListener(), true, true, false);
 
+        registerForHostEvents(new SetHostParamsListener(), true, true, false);
+
         _executor = new ThreadPoolExecutor(threads, threads, 60l, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(), new NamedThreadFactory("AgentTaskPool"));
 
         _connectExecutor = new ThreadPoolExecutor(100, 500, 60l, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(), new NamedThreadFactory("AgentConnectTaskPool"));
@@ -1710,4 +1713,73 @@
                         DirectAgentThreadCap };
     }
 
+    protected class SetHostParamsListener implements Listener {
+        @Override
+        public boolean isRecurring() {
+            return false;
+        }
+
+        @Override
+        public boolean processAnswers(final long agentId, final long seq, final Answer[] answers) {
+            return false;
+        }
+
+        @Override
+        public boolean processCommands(final long agentId, final long seq, final Command[] commands) {
+            return false;
+        }
+
+        @Override
+        public AgentControlAnswer processControlCommand(final long agentId, final AgentControlCommand cmd) {
+            return null;
+        }
+
+        @Override
+        public void processHostAdded(long hostId) {
+        }
+
+        @Override
+        public void processConnect(final Host host, final StartupCommand cmd, final boolean forRebalance) {
+        if (cmd instanceof StartupRoutingCommand) {
+            if (((StartupRoutingCommand)cmd).getHypervisorType() == HypervisorType.KVM || ((StartupRoutingCommand)cmd).getHypervisorType() == HypervisorType.LXC) {
+                Map<String, String> params = new HashMap<String, String>();
+                params.put("router.aggregation.command.each.timeout", _configDao.getValue("router.aggregation.command.each.timeout"));
+
+                try {
+                    SetHostParamsCommand cmds = new SetHostParamsCommand(params);
+                    Commands c = new Commands(cmds);
+                    send(host.getId(), c, this);
+                } catch (AgentUnavailableException e) {
+                    s_logger.debug("Failed to send host params on host: " + host.getId());
+                }
+            }
+        }
+
+        }
+
+        @Override
+        public boolean processDisconnect(final long agentId, final Status state) {
+            return true;
+        }
+
+        @Override
+        public void processHostAboutToBeRemoved(long hostId) {
+        }
+
+        @Override
+        public void processHostRemoved(long hostId, long clusterId) {
+        }
+
+        @Override
+        public boolean processTimeout(final long agentId, final long seq) {
+            return false;
+        }
+
+        @Override
+        public int getTimeout() {
+            return -1;
+        }
+
+    }
+
 }
diff --git a/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java b/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java
index bea98cb..03a3798 100644
--- a/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java
+++ b/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java
@@ -744,14 +744,17 @@
 
     protected <T extends VMInstanceVO> boolean changeState(final T vm, final Event event, final Long hostId, final ItWorkVO work, final Step step) throws NoTransitionException {
         // FIXME: We should do this better.
-        final Step previousStep = work.getStep();
-        _workDao.updateStep(work, step);
+        Step previousStep = null;
+        if (work != null) {
+            previousStep = work.getStep();
+            _workDao.updateStep(work, step);
+        }
         boolean result = false;
         try {
             result = stateTransitTo(vm, event, hostId);
             return result;
         } finally {
-            if (!result) {
+            if (!result && work != null) {
                 _workDao.updateStep(work, previousStep);
             }
         }
@@ -1507,12 +1510,13 @@
             if (doCleanup) {
                 if (cleanup(vmGuru, new VirtualMachineProfileImpl(vm), work, Event.StopRequested, cleanUpEvenIfUnableToStop)) {
                     try {
-                        if (s_logger.isDebugEnabled()) {
+                        if (s_logger.isDebugEnabled() && work != null) {
                             s_logger.debug("Updating work item to Done, id:" + work.getId());
                         }
                         if (!changeState(vm, Event.AgentReportStopped, null, work, Step.Done)) {
                             throw new CloudRuntimeException("Unable to stop " + vm);
                         }
+
                     } catch (final NoTransitionException e) {
                         s_logger.warn("Unable to cleanup " + vm);
                         throw new CloudRuntimeException("Unable to stop " + vm, e);
diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java b/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java
index 66185c6..60c2694 100644
--- a/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java
+++ b/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java
@@ -2025,7 +2025,7 @@
         // Check if cidr is RFC1918 compliant if the network is Guest Isolated for IPv4
         if (cidr != null && ntwkOff.getGuestType() == Network.GuestType.Isolated && ntwkOff.getTrafficType() == TrafficType.Guest) {
             if (!NetUtils.validateGuestCidr(cidr)) {
-                throw new InvalidParameterValueException("Virtual Guest Cidr " + cidr + " is not RFC1918 compliant");
+                throw new InvalidParameterValueException("Virtual Guest Cidr " + cidr + " is not RFC 1918 or 6598 compliant");
             }
         }
 
diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java b/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java
index ca4ef4f..ea6a66d 100644
--- a/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java
+++ b/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java
@@ -44,7 +44,10 @@
 import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory;
 import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo;
 import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotService;
+import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotStrategy;
+import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotStrategy.SnapshotOperation;
 import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator;
+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.VolumeDataFactory;
@@ -178,6 +181,8 @@
     ClusterManager clusterManager;
     @Inject
     StorageManager storageMgr;
+    @Inject
+    StorageStrategyFactory _storageStrategyFactory;
 
     private final StateMachine2<Volume.State, Volume.Event, Volume> _volStateMachine;
     protected List<StoragePoolAllocator> _storagePoolAllocators;
@@ -383,6 +388,24 @@
         DataStoreRole dataStoreRole = getDataStoreRole(snapshot);
         SnapshotInfo snapInfo = snapshotFactory.getSnapshot(snapshot.getId(), dataStoreRole);
 
+
+        if(snapInfo == null && dataStoreRole == DataStoreRole.Image) {
+            // snapshot is not backed up to secondary, let's do that now.
+            snapInfo = snapshotFactory.getSnapshot(snapshot.getId(), DataStoreRole.Primary);
+
+            if (snapInfo == null) {
+                throw new CloudRuntimeException("Cannot find snapshot " + snapshot.getId());
+            }
+            // We need to copy the snapshot onto secondary.
+            SnapshotStrategy snapshotStrategy = _storageStrategyFactory.getSnapshotStrategy(snapshot, SnapshotOperation.BACKUP);
+            snapshotStrategy.backupSnapshot(snapInfo);
+
+            // Attempt to grab it again.
+            snapInfo = snapshotFactory.getSnapshot(snapshot.getId(), dataStoreRole);
+            if (snapInfo == null) {
+                throw new CloudRuntimeException("Cannot find snapshot " + snapshot.getId() + " on secondary and could not create backup");
+            }
+        }
         // don't try to perform a sync if the DataStoreRole of the snapshot is equal to DataStoreRole.Primary
         if (!DataStoreRole.Primary.equals(dataStoreRole)) {
             try {
diff --git a/engine/pom.xml b/engine/pom.xml
index 5d49759..4f79c1b 100644
--- a/engine/pom.xml
+++ b/engine/pom.xml
@@ -24,7 +24,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../pom.xml</relativePath>
   </parent>
   <build>
diff --git a/engine/schema/pom.xml b/engine/schema/pom.xml
index 6b2a421..8f3e761 100644
--- a/engine/schema/pom.xml
+++ b/engine/schema/pom.xml
@@ -24,7 +24,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloud-engine</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../pom.xml</relativePath>
   </parent>
   <dependencies>
diff --git a/engine/schema/src/com/cloud/capacity/dao/CapacityDaoImpl.java b/engine/schema/src/com/cloud/capacity/dao/CapacityDaoImpl.java
index 1b1b856..95d57d0 100644
--- a/engine/schema/src/com/cloud/capacity/dao/CapacityDaoImpl.java
+++ b/engine/schema/src/com/cloud/capacity/dao/CapacityDaoImpl.java
@@ -23,7 +23,6 @@
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.Map.Entry;
 
 import javax.inject.Inject;
 
@@ -356,11 +355,11 @@
 
         switch (level) {
         case 1: // List all the capacities grouped by zone, capacity Type
-            finalQuery.append(LIST_CAPACITY_GROUP_BY_CLUSTER_TYPE_PART2);
+            finalQuery.append(LIST_CAPACITY_GROUP_BY_ZONE_TYPE_PART2);
             break;
 
         case 2: // List all the capacities grouped by pod, capacity Type
-            finalQuery.append(LIST_CAPACITY_GROUP_BY_CLUSTER_TYPE_PART2);
+            finalQuery.append(LIST_CAPACITY_GROUP_BY_POD_TYPE_PART2);
             break;
 
         case 3: // List all the capacities grouped by cluster, capacity Type
@@ -392,22 +391,7 @@
                 results.add(summedCapacity);
             }
 
-            HashMap<Integer, SummedCapacity> capacityMap = new HashMap<Integer, SummedCapacity>();
-            for (SummedCapacity result: results) {
-                if (capacityMap.containsKey(result.getCapacityType().intValue())) {
-                    SummedCapacity tempCapacity = capacityMap.get(result.getCapacityType().intValue());
-                    tempCapacity.setUsedCapacity(tempCapacity.getUsedCapacity()+result.getUsedCapacity());
-                    tempCapacity.setReservedCapacity(tempCapacity.getReservedCapacity()+result.getReservedCapacity());
-                    tempCapacity.setSumTotal(tempCapacity.getTotalCapacity()+result.getTotalCapacity());
-                }else {
-                    capacityMap.put(result.getCapacityType().intValue(),result);
-                }
-            }
-            List<SummedCapacity> summedCapacityList = new ArrayList<SummedCapacity>();
-            for (Entry<Integer, SummedCapacity> entry : capacityMap.entrySet()) {
-                summedCapacityList.add(entry.getValue());
-            }
-            return summedCapacityList;
+            return results;
         } catch (SQLException e) {
             throw new CloudRuntimeException("DB Exception on: " + finalQuery, e);
         } catch (Throwable e) {
diff --git a/engine/schema/src/com/cloud/dc/dao/ClusterDao.java b/engine/schema/src/com/cloud/dc/dao/ClusterDao.java
index 06bc5a3..de8d604 100644
--- a/engine/schema/src/com/cloud/dc/dao/ClusterDao.java
+++ b/engine/schema/src/com/cloud/dc/dao/ClusterDao.java
@@ -16,13 +16,13 @@
 // under the License.
 package com.cloud.dc.dao;
 
-import java.util.List;
-import java.util.Map;
-
 import com.cloud.dc.ClusterVO;
 import com.cloud.hypervisor.Hypervisor.HypervisorType;
 import com.cloud.utils.db.GenericDao;
 
+import java.util.List;
+import java.util.Map;
+
 public interface ClusterDao extends GenericDao<ClusterVO, Long> {
     List<ClusterVO> listByPodId(long podId);
 
@@ -44,7 +44,7 @@
 
     List<ClusterVO> listClustersByDcId(long zoneId);
 
-    List<Long> listAllCusters(long zoneId);
+    List<Long> listAllClusters(Long zoneId);
 
     boolean getSupportsResigning(long clusterId);
 }
diff --git a/engine/schema/src/com/cloud/dc/dao/ClusterDaoImpl.java b/engine/schema/src/com/cloud/dc/dao/ClusterDaoImpl.java
index 0c5bd6f..b1fce61 100644
--- a/engine/schema/src/com/cloud/dc/dao/ClusterDaoImpl.java
+++ b/engine/schema/src/com/cloud/dc/dao/ClusterDaoImpl.java
@@ -16,18 +16,6 @@
 // under the License.
 package com.cloud.dc.dao;
 
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.inject.Inject;
-
-import org.springframework.stereotype.Component;
-
 import com.cloud.dc.ClusterDetailsDao;
 import com.cloud.dc.ClusterDetailsVO;
 import com.cloud.dc.ClusterVO;
@@ -43,6 +31,16 @@
 import com.cloud.utils.db.SearchCriteria.Op;
 import com.cloud.utils.db.TransactionLegacy;
 import com.cloud.utils.exception.CloudRuntimeException;
+import org.springframework.stereotype.Component;
+
+import javax.inject.Inject;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 
 @Component
 public class ClusterDaoImpl extends GenericDaoBase<ClusterVO, Long> implements ClusterDao {
@@ -259,9 +257,11 @@
     }
 
     @Override
-    public List<Long> listAllCusters(long zoneId) {
+    public List<Long> listAllClusters(Long zoneId) {
         SearchCriteria<Long> sc = ClusterIdSearch.create();
-        sc.setParameters("dataCenterId", zoneId);
+        if (zoneId != null) {
+            sc.setParameters("dataCenterId", zoneId);
+        }
         return customSearch(sc, null);
     }
 
diff --git a/engine/schema/src/com/cloud/dc/dao/HostPodDao.java b/engine/schema/src/com/cloud/dc/dao/HostPodDao.java
index 39c8a49..1a000d8 100644
--- a/engine/schema/src/com/cloud/dc/dao/HostPodDao.java
+++ b/engine/schema/src/com/cloud/dc/dao/HostPodDao.java
@@ -31,5 +31,5 @@
 
     public List<Long> listDisabledPods(long zoneId);
 
-    public List<Long> listAllPods(long zoneId);
+    public List<Long> listAllPods(Long zoneId);
 }
diff --git a/engine/schema/src/com/cloud/dc/dao/HostPodDaoImpl.java b/engine/schema/src/com/cloud/dc/dao/HostPodDaoImpl.java
index 8d689e3..1c83b3a4 100644
--- a/engine/schema/src/com/cloud/dc/dao/HostPodDaoImpl.java
+++ b/engine/schema/src/com/cloud/dc/dao/HostPodDaoImpl.java
@@ -130,9 +130,11 @@
     }
 
     @Override
-    public List<Long> listAllPods(long zoneId) {
+    public List<Long> listAllPods(Long zoneId) {
         SearchCriteria<Long> sc = PodIdSearch.create();
-        sc.addAnd("dataCenterId", SearchCriteria.Op.EQ, zoneId);
+        if (zoneId != null) {
+            sc.addAnd("dataCenterId", SearchCriteria.Op.EQ, zoneId);
+        }
         return customSearch(sc, null);
     }
 }
diff --git a/engine/schema/src/com/cloud/upgrade/DatabaseUpgradeChecker.java b/engine/schema/src/com/cloud/upgrade/DatabaseUpgradeChecker.java
index 3344a22..bb4fd1a 100644
--- a/engine/schema/src/com/cloud/upgrade/DatabaseUpgradeChecker.java
+++ b/engine/schema/src/com/cloud/upgrade/DatabaseUpgradeChecker.java
@@ -280,7 +280,7 @@
 
         _upgradeMap.put(CloudStackVersion.parse("4.9.0"), new DbUpgrade[] {new Upgrade490to4910(), new Upgrade4910to4920()});
 
-        _upgradeMap.put(CloudStackVersion.parse("4.9.1.0"), new DbUpgrade[] {new Upgrade490to4910(), new Upgrade4910to4920()});
+        _upgradeMap.put(CloudStackVersion.parse("4.9.1.0"), new DbUpgrade[] {new Upgrade4910to4920()});
 
         //CP Upgrades
         _upgradeMap.put(CloudStackVersion.parse("3.0.3"), new DbUpgrade[] {new Upgrade303to304(), new Upgrade304to305(), new Upgrade305to306(), new Upgrade306to307(), new Upgrade307to410(),
diff --git a/engine/service/pom.xml b/engine/service/pom.xml
index 9a9fb20..a8d8db2 100644
--- a/engine/service/pom.xml
+++ b/engine/service/pom.xml
@@ -23,7 +23,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloud-engine</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
   </parent>
   <artifactId>cloud-engine-service</artifactId>
   <packaging>war</packaging>
diff --git a/engine/storage/cache/pom.xml b/engine/storage/cache/pom.xml
index b9a2d0c..2a2a2d2 100644
--- a/engine/storage/cache/pom.xml
+++ b/engine/storage/cache/pom.xml
@@ -15,7 +15,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloud-engine</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../../pom.xml</relativePath>
   </parent>
   <dependencies>
diff --git a/engine/storage/datamotion/pom.xml b/engine/storage/datamotion/pom.xml
index 65bbb3e..6545ca0 100644
--- a/engine/storage/datamotion/pom.xml
+++ b/engine/storage/datamotion/pom.xml
@@ -16,7 +16,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloud-engine</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../../pom.xml</relativePath>
   </parent>
   <dependencies>
diff --git a/engine/storage/image/pom.xml b/engine/storage/image/pom.xml
index 867b495..af47a4c 100644
--- a/engine/storage/image/pom.xml
+++ b/engine/storage/image/pom.xml
@@ -16,7 +16,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloud-engine</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../../pom.xml</relativePath>
   </parent>
   <dependencies>
diff --git a/engine/storage/integration-test/pom.xml b/engine/storage/integration-test/pom.xml
index cabfea2..3e99429 100644
--- a/engine/storage/integration-test/pom.xml
+++ b/engine/storage/integration-test/pom.xml
@@ -16,7 +16,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloud-engine</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../../pom.xml</relativePath>
   </parent>
   <dependencies>
diff --git a/engine/storage/pom.xml b/engine/storage/pom.xml
index d67edb4..124252b 100644
--- a/engine/storage/pom.xml
+++ b/engine/storage/pom.xml
@@ -16,7 +16,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloud-engine</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../pom.xml</relativePath>
   </parent>
   <dependencies>
diff --git a/engine/storage/snapshot/pom.xml b/engine/storage/snapshot/pom.xml
index 17fa63c..731d43f 100644
--- a/engine/storage/snapshot/pom.xml
+++ b/engine/storage/snapshot/pom.xml
@@ -16,7 +16,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloud-engine</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../../pom.xml</relativePath>
   </parent>
   <dependencies>
diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotStateMachineManagerImpl.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotStateMachineManagerImpl.java
index cf5944b..1cec2dc 100644
--- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotStateMachineManagerImpl.java
+++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotStateMachineManagerImpl.java
@@ -47,6 +47,7 @@
         stateMachine.addTransition(Snapshot.State.BackingUp, Event.OperationFailed, Snapshot.State.Error);
         stateMachine.addTransition(Snapshot.State.BackedUp, Event.DestroyRequested, Snapshot.State.Destroying);
         stateMachine.addTransition(Snapshot.State.BackedUp, Event.CopyingRequested, Snapshot.State.Copying);
+        stateMachine.addTransition(Snapshot.State.BackedUp, Event.BackupToSecondary, Snapshot.State.BackingUp);
         stateMachine.addTransition(Snapshot.State.Copying, Event.OperationSucceeded, Snapshot.State.BackedUp);
         stateMachine.addTransition(Snapshot.State.Copying, Event.OperationFailed, Snapshot.State.BackedUp);
         stateMachine.addTransition(Snapshot.State.Destroying, Event.OperationSucceeded, Snapshot.State.Destroyed);
diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/XenserverSnapshotStrategy.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/XenserverSnapshotStrategy.java
index 5771d9f..2686e40 100644
--- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/XenserverSnapshotStrategy.java
+++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/XenserverSnapshotStrategy.java
@@ -39,6 +39,7 @@
 import org.apache.cloudstack.storage.datastore.PrimaryDataStoreImpl;
 import org.apache.cloudstack.storage.to.SnapshotObjectTO;
 
+import com.cloud.configuration.Config;
 import com.cloud.exception.InvalidParameterValueException;
 import com.cloud.hypervisor.Hypervisor;
 import com.cloud.hypervisor.Hypervisor.HypervisorType;
@@ -376,8 +377,24 @@
 
             snapshot = result.getSnashot();
             DataStore primaryStore = snapshot.getDataStore();
+            boolean backupFlag = Boolean.parseBoolean(configDao.getValue(Config.BackupSnapshotAfterTakingSnapshot.toString()));
 
-            SnapshotInfo backupedSnapshot = backupSnapshot(snapshot);
+            SnapshotInfo backupedSnapshot;
+            if(backupFlag) {
+                backupedSnapshot = backupSnapshot(snapshot);
+            } else {
+                // Fake it to get the transitions to fire in the proper order
+                s_logger.debug("skipping backup of snapshot due to configuration "+Config.BackupSnapshotAfterTakingSnapshot.toString());
+
+                SnapshotObject snapObj = (SnapshotObject)snapshot;
+                try {
+                    snapObj.processEvent(Snapshot.Event.OperationNotPerformed);
+                } catch (NoTransitionException e) {
+                    s_logger.debug("Failed to change state: " + snapshot.getId() + ": " + e.toString());
+                    throw new CloudRuntimeException(e.toString());
+                }
+                backupedSnapshot = snapshot;
+            }
 
             try {
                 SnapshotInfo parent = snapshot.getParent();
diff --git a/engine/storage/volume/pom.xml b/engine/storage/volume/pom.xml
index 0abc066..bd23736 100644
--- a/engine/storage/volume/pom.xml
+++ b/engine/storage/volume/pom.xml
@@ -16,7 +16,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloud-engine</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../../pom.xml</relativePath>
   </parent>
   <dependencies>
diff --git a/framework/cluster/pom.xml b/framework/cluster/pom.xml
index cb60bfc..997c532 100644
--- a/framework/cluster/pom.xml
+++ b/framework/cluster/pom.xml
@@ -15,7 +15,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack-framework</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../pom.xml</relativePath>
   </parent>
   <dependencies>
diff --git a/framework/config/pom.xml b/framework/config/pom.xml
index 821927b..aa03e70 100644
--- a/framework/config/pom.xml
+++ b/framework/config/pom.xml
@@ -15,7 +15,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack-framework</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../pom.xml</relativePath>
   </parent>
   <dependencies>
diff --git a/framework/db/pom.xml b/framework/db/pom.xml
index 9a0d2b7..421ca5f 100644
--- a/framework/db/pom.xml
+++ b/framework/db/pom.xml
@@ -15,7 +15,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack-framework</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../pom.xml</relativePath>
   </parent>
   <dependencies>
diff --git a/framework/events/pom.xml b/framework/events/pom.xml
index b46cec0..62bf8b8 100644
--- a/framework/events/pom.xml
+++ b/framework/events/pom.xml
@@ -15,7 +15,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack-framework</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../pom.xml</relativePath>
   </parent>
   <dependencies>
diff --git a/framework/ipc/pom.xml b/framework/ipc/pom.xml
index f89a30b..2caf2cd 100644
--- a/framework/ipc/pom.xml
+++ b/framework/ipc/pom.xml
@@ -16,7 +16,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack-framework</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../pom.xml</relativePath>
   </parent>
   <dependencies>
diff --git a/framework/jobs/pom.xml b/framework/jobs/pom.xml
index e8f6338..d5f7ab6 100644
--- a/framework/jobs/pom.xml
+++ b/framework/jobs/pom.xml
@@ -23,7 +23,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack-framework</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../pom.xml</relativePath>
   </parent>  
   <dependencies>
diff --git a/framework/managed-context/pom.xml b/framework/managed-context/pom.xml
index cc5a3b5..e5c652a 100644
--- a/framework/managed-context/pom.xml
+++ b/framework/managed-context/pom.xml
@@ -24,7 +24,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloud-maven-standard</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../../maven-standard/pom.xml</relativePath>
   </parent>
   <dependencies>
diff --git a/framework/pom.xml b/framework/pom.xml
index 3211305..1bbbc20 100644
--- a/framework/pom.xml
+++ b/framework/pom.xml
@@ -24,7 +24,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
   </parent>
   <build>
     <defaultGoal>install</defaultGoal>
diff --git a/framework/quota/pom.xml b/framework/quota/pom.xml
index f9570fb..a39a0bd 100644
--- a/framework/quota/pom.xml
+++ b/framework/quota/pom.xml
@@ -23,7 +23,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack-framework</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../pom.xml</relativePath>
   </parent>
   <dependencies>
diff --git a/framework/rest/pom.xml b/framework/rest/pom.xml
index d65a501..cd26557 100644
--- a/framework/rest/pom.xml
+++ b/framework/rest/pom.xml
@@ -22,7 +22,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack-framework</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../pom.xml</relativePath>
   </parent>
   <artifactId>cloud-framework-rest</artifactId>
diff --git a/framework/security/pom.xml b/framework/security/pom.xml
index 557f835..07ebc05 100644
--- a/framework/security/pom.xml
+++ b/framework/security/pom.xml
@@ -23,7 +23,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack-framework</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../pom.xml</relativePath>
   </parent>
   <dependencies>
diff --git a/framework/spring/lifecycle/pom.xml b/framework/spring/lifecycle/pom.xml
index 26190af..f38cc71 100644
--- a/framework/spring/lifecycle/pom.xml
+++ b/framework/spring/lifecycle/pom.xml
@@ -16,7 +16,7 @@
     <parent>
         <groupId>org.apache.cloudstack</groupId>
         <artifactId>cloud-maven-standard</artifactId>
-        <version>4.9.2.0-SNAPSHOT</version>
+        <version>4.9.3.0-SNAPSHOT</version>
         <relativePath>../../../maven-standard/pom.xml</relativePath>
     </parent>
     <dependencies>
diff --git a/framework/spring/module/pom.xml b/framework/spring/module/pom.xml
index dd16444..a5cdce4 100644
--- a/framework/spring/module/pom.xml
+++ b/framework/spring/module/pom.xml
@@ -24,7 +24,7 @@
     <parent>
         <groupId>org.apache.cloudstack</groupId>
         <artifactId>cloud-maven-standard</artifactId>
-        <version>4.9.2.0-SNAPSHOT</version>
+        <version>4.9.3.0-SNAPSHOT</version>
         <relativePath>../../../maven-standard/pom.xml</relativePath>
     </parent>
     <dependencies>
diff --git a/maven-standard/pom.xml b/maven-standard/pom.xml
index 88e5ab7..88c5668 100644
--- a/maven-standard/pom.xml
+++ b/maven-standard/pom.xml
@@ -25,7 +25,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../pom.xml</relativePath>
   </parent>
   <build>
diff --git a/packaging/centos63/cloud-agent.rc b/packaging/centos63/cloud-agent.rc
index aad9582..870a35a 100755
--- a/packaging/centos63/cloud-agent.rc
+++ b/packaging/centos63/cloud-agent.rc
@@ -2,6 +2,7 @@
 
 # chkconfig: 35 99 10
 # description: Cloud Agent
+# pidfile: /var/run/cloudstack-agent.pid
 
 # Licensed to the Apache Software Foundation (ASF) under one
 # or more contributor license agreements.  See the NOTICE file
diff --git a/packaging/centos63/cloud.spec b/packaging/centos63/cloud.spec
index 9556236..87a60c3 100644
--- a/packaging/centos63/cloud.spec
+++ b/packaging/centos63/cloud.spec
@@ -440,7 +440,7 @@
 fi
 
 grep -s -q "db.cloud.driver=jdbc:mysql" "%{_sysconfdir}/%{name}/management/db.properties" || sed -i -e "\$adb.cloud.driver=jdbc:mysql" "%{_sysconfdir}/%{name}/management/db.properties"
-grep -s -q "db.usage.driver=jdbc:mysql" "%{_sysconfdir}/%{name}/management/db.properties" || sed -i -e "\$adb.usage.driver=jdbc:mysql" db.properties
+grep -s -q "db.usage.driver=jdbc:mysql" "%{_sysconfdir}/%{name}/management/db.properties" || sed -i -e "\$adb.usage.driver=jdbc:mysql" "%{_sysconfdir}/%{name}/management/db.properties"
 grep -s -q "db.simulator.driver=jdbc:mysql" "%{_sysconfdir}/%{name}/management/db.properties" || sed -i -e "\$adb.simulator.driver=jdbc:mysql" "%{_sysconfdir}/%{name}/management/db.properties"
 
 if [ ! -f %{_datadir}/cloudstack-common/scripts/vm/hypervisor/xenserver/vhd-util ] ; then
diff --git a/packaging/centos7/cloud-agent.rc b/packaging/centos7/cloud-agent.rc
index aad9582..870a35a 100755
--- a/packaging/centos7/cloud-agent.rc
+++ b/packaging/centos7/cloud-agent.rc
@@ -2,6 +2,7 @@
 
 # chkconfig: 35 99 10
 # description: Cloud Agent
+# pidfile: /var/run/cloudstack-agent.pid
 
 # Licensed to the Apache Software Foundation (ASF) under one
 # or more contributor license agreements.  See the NOTICE file
diff --git a/packaging/centos7/cloud.spec b/packaging/centos7/cloud.spec
index 7c093f9..74f60e7 100644
--- a/packaging/centos7/cloud.spec
+++ b/packaging/centos7/cloud.spec
@@ -397,7 +397,7 @@
 fi
 
 grep -s -q "db.cloud.driver=jdbc:mysql" "%{_sysconfdir}/%{name}/management/db.properties" || sed -i -e "\$adb.cloud.driver=jdbc:mysql" "%{_sysconfdir}/%{name}/management/db.properties"
-grep -s -q "db.usage.driver=jdbc:mysql" "%{_sysconfdir}/%{name}/management/db.properties" || sed -i -e "\$adb.usage.driver=jdbc:mysql" db.properties
+grep -s -q "db.usage.driver=jdbc:mysql" "%{_sysconfdir}/%{name}/management/db.properties" || sed -i -e "\$adb.usage.driver=jdbc:mysql"  "%{_sysconfdir}/%{name}/management/db.properties"
 grep -s -q "db.simulator.driver=jdbc:mysql" "%{_sysconfdir}/%{name}/management/db.properties" || sed -i -e "\$adb.simulator.driver=jdbc:mysql" "%{_sysconfdir}/%{name}/management/db.properties"
 
 if [ ! -f %{_datadir}/cloudstack-common/scripts/vm/hypervisor/xenserver/vhd-util ] ; then
diff --git a/packaging/centos7/tomcat7/db.properties b/packaging/centos7/tomcat7/db.properties
index 6161f3a..94376f7 100644
--- a/packaging/centos7/tomcat7/db.properties
+++ b/packaging/centos7/tomcat7/db.properties
@@ -39,7 +39,7 @@
 db.cloud.timeBetweenEvictionRunsMillis=40000
 db.cloud.minEvictableIdleTimeMillis=240000
 db.cloud.poolPreparedStatements=false
-db.cloud.url.params=prepStmtCacheSize=517&cachePrepStmts=true
+db.cloud.url.params=prepStmtCacheSize=517&cachePrepStmts=true&sessionVariables=sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'
 
 # CloudStack database SSL settings
 db.cloud.useSSL=false
diff --git a/packaging/fedora20/cloud-agent.rc b/packaging/fedora20/cloud-agent.rc
index 6cc6abc..2defa14 100755
--- a/packaging/fedora20/cloud-agent.rc
+++ b/packaging/fedora20/cloud-agent.rc
@@ -2,6 +2,7 @@
 
 # chkconfig: 35 99 10
 # description: Cloud Agent
+# pidfile: /var/run/cloudstack-agent.pid
 
 # Licensed to the Apache Software Foundation (ASF) under one
 # or more contributor license agreements.  See the NOTICE file
diff --git a/packaging/fedora21/cloud-agent.rc b/packaging/fedora21/cloud-agent.rc
index 6cc6abc..2defa14 100755
--- a/packaging/fedora21/cloud-agent.rc
+++ b/packaging/fedora21/cloud-agent.rc
@@ -2,6 +2,7 @@
 
 # chkconfig: 35 99 10
 # description: Cloud Agent
+# pidfile: /var/run/cloudstack-agent.pid
 
 # Licensed to the Apache Software Foundation (ASF) under one
 # or more contributor license agreements.  See the NOTICE file
diff --git a/plugins/acl/dynamic-role-based/pom.xml b/plugins/acl/dynamic-role-based/pom.xml
index fe672ec..c11ca3a 100644
--- a/plugins/acl/dynamic-role-based/pom.xml
+++ b/plugins/acl/dynamic-role-based/pom.xml
@@ -26,7 +26,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack-plugins</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../../pom.xml</relativePath>
   </parent>
 </project>
diff --git a/plugins/acl/static-role-based/pom.xml b/plugins/acl/static-role-based/pom.xml
index e7c6ed4..5a53743 100644
--- a/plugins/acl/static-role-based/pom.xml
+++ b/plugins/acl/static-role-based/pom.xml
@@ -26,7 +26,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack-plugins</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../../pom.xml</relativePath>
   </parent>
 </project>
diff --git a/plugins/affinity-group-processors/explicit-dedication/pom.xml b/plugins/affinity-group-processors/explicit-dedication/pom.xml
index 510c7c0..d0624bb 100644
--- a/plugins/affinity-group-processors/explicit-dedication/pom.xml
+++ b/plugins/affinity-group-processors/explicit-dedication/pom.xml
@@ -23,7 +23,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack-plugins</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../../pom.xml</relativePath>
   </parent>
   <build>
diff --git a/plugins/affinity-group-processors/host-anti-affinity/pom.xml b/plugins/affinity-group-processors/host-anti-affinity/pom.xml
index 61c4351..647a61f 100644
--- a/plugins/affinity-group-processors/host-anti-affinity/pom.xml
+++ b/plugins/affinity-group-processors/host-anti-affinity/pom.xml
@@ -23,7 +23,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack-plugins</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../../pom.xml</relativePath>
   </parent>
   <build>
diff --git a/plugins/alert-handlers/snmp-alerts/pom.xml b/plugins/alert-handlers/snmp-alerts/pom.xml
index 55be59a..d28a672 100644
--- a/plugins/alert-handlers/snmp-alerts/pom.xml
+++ b/plugins/alert-handlers/snmp-alerts/pom.xml
@@ -22,7 +22,7 @@
   <parent>
     <artifactId>cloudstack-plugins</artifactId>
     <groupId>org.apache.cloudstack</groupId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../../pom.xml</relativePath>
   </parent>
   <modelVersion>4.0.0</modelVersion>
diff --git a/plugins/alert-handlers/syslog-alerts/pom.xml b/plugins/alert-handlers/syslog-alerts/pom.xml
index 78d7b0b..af3d2ff 100644
--- a/plugins/alert-handlers/syslog-alerts/pom.xml
+++ b/plugins/alert-handlers/syslog-alerts/pom.xml
@@ -22,7 +22,7 @@
   <parent>
     <artifactId>cloudstack-plugins</artifactId>
     <groupId>org.apache.cloudstack</groupId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../../pom.xml</relativePath>
   </parent>
   <modelVersion>4.0.0</modelVersion>
diff --git a/plugins/api/discovery/pom.xml b/plugins/api/discovery/pom.xml
index ab36b3e..c58acd7 100644
--- a/plugins/api/discovery/pom.xml
+++ b/plugins/api/discovery/pom.xml
@@ -26,7 +26,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack-plugins</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../../pom.xml</relativePath>
   </parent>
   <dependencies>
diff --git a/plugins/api/rate-limit/pom.xml b/plugins/api/rate-limit/pom.xml
index 0f5a9a5..a37a229 100644
--- a/plugins/api/rate-limit/pom.xml
+++ b/plugins/api/rate-limit/pom.xml
@@ -23,7 +23,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack-plugins</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../../pom.xml</relativePath>
   </parent>
   <build>
diff --git a/plugins/api/solidfire-intg-test/pom.xml b/plugins/api/solidfire-intg-test/pom.xml
index fcadb6d..28e9ca3 100644
--- a/plugins/api/solidfire-intg-test/pom.xml
+++ b/plugins/api/solidfire-intg-test/pom.xml
@@ -23,7 +23,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack-plugins</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../../pom.xml</relativePath>
   </parent>
   <dependencies>
diff --git a/plugins/database/mysql-ha/pom.xml b/plugins/database/mysql-ha/pom.xml
index dc3ebcf..9340540 100644
--- a/plugins/database/mysql-ha/pom.xml
+++ b/plugins/database/mysql-ha/pom.xml
@@ -15,7 +15,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack-plugins</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../../pom.xml</relativePath>
   </parent>
   <dependencies>
diff --git a/plugins/database/quota/pom.xml b/plugins/database/quota/pom.xml
index d990daa..edb52c9 100644
--- a/plugins/database/quota/pom.xml
+++ b/plugins/database/quota/pom.xml
@@ -16,7 +16,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack-plugins</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../../pom.xml</relativePath>
   </parent>
   <dependencies>
diff --git a/plugins/dedicated-resources/pom.xml b/plugins/dedicated-resources/pom.xml
index 4c4b28e..3fa0f70 100644
--- a/plugins/dedicated-resources/pom.xml
+++ b/plugins/dedicated-resources/pom.xml
@@ -23,7 +23,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack-plugins</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../pom.xml</relativePath>
   </parent>
 </project>
diff --git a/plugins/deployment-planners/implicit-dedication/pom.xml b/plugins/deployment-planners/implicit-dedication/pom.xml
index bbc7fc5..a0335e4 100644
--- a/plugins/deployment-planners/implicit-dedication/pom.xml
+++ b/plugins/deployment-planners/implicit-dedication/pom.xml
@@ -23,7 +23,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack-plugins</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../../pom.xml</relativePath>
   </parent>
 </project>
diff --git a/plugins/deployment-planners/user-concentrated-pod/pom.xml b/plugins/deployment-planners/user-concentrated-pod/pom.xml
index 470761e..7664278 100644
--- a/plugins/deployment-planners/user-concentrated-pod/pom.xml
+++ b/plugins/deployment-planners/user-concentrated-pod/pom.xml
@@ -23,7 +23,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack-plugins</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../../pom.xml</relativePath>
   </parent>
 </project>
diff --git a/plugins/deployment-planners/user-dispersing/pom.xml b/plugins/deployment-planners/user-dispersing/pom.xml
index bd5b1d9..52fd62f 100644
--- a/plugins/deployment-planners/user-dispersing/pom.xml
+++ b/plugins/deployment-planners/user-dispersing/pom.xml
@@ -23,7 +23,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack-plugins</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../../pom.xml</relativePath>
   </parent>
 </project>
diff --git a/plugins/event-bus/inmemory/pom.xml b/plugins/event-bus/inmemory/pom.xml
index 56e682f..d77a35a 100644
--- a/plugins/event-bus/inmemory/pom.xml
+++ b/plugins/event-bus/inmemory/pom.xml
@@ -24,7 +24,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack-plugins</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../../pom.xml</relativePath>
   </parent>
   <dependencies>
diff --git a/plugins/event-bus/kafka/pom.xml b/plugins/event-bus/kafka/pom.xml
index 240db43..9ba1c52 100644
--- a/plugins/event-bus/kafka/pom.xml
+++ b/plugins/event-bus/kafka/pom.xml
@@ -24,7 +24,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack-plugins</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../../pom.xml</relativePath>
   </parent>
   <dependencies>
diff --git a/plugins/event-bus/rabbitmq/pom.xml b/plugins/event-bus/rabbitmq/pom.xml
index 64e2814..6b5f3eb 100644
--- a/plugins/event-bus/rabbitmq/pom.xml
+++ b/plugins/event-bus/rabbitmq/pom.xml
@@ -24,7 +24,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack-plugins</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../../pom.xml</relativePath>
   </parent>
   <dependencies>
diff --git a/plugins/file-systems/netapp/pom.xml b/plugins/file-systems/netapp/pom.xml
index d4fc827..10e9f05 100644
--- a/plugins/file-systems/netapp/pom.xml
+++ b/plugins/file-systems/netapp/pom.xml
@@ -23,7 +23,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack-plugins</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../../pom.xml</relativePath>
   </parent>
   <dependencies>
diff --git a/plugins/ha-planners/skip-heurestics/pom.xml b/plugins/ha-planners/skip-heurestics/pom.xml
index 26de0b6..fca59d8 100644
--- a/plugins/ha-planners/skip-heurestics/pom.xml
+++ b/plugins/ha-planners/skip-heurestics/pom.xml
@@ -23,7 +23,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack-plugins</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../../pom.xml</relativePath>
   </parent>
 </project>
diff --git a/plugins/host-allocators/random/pom.xml b/plugins/host-allocators/random/pom.xml
index fc1d0ab..aae1266 100644
--- a/plugins/host-allocators/random/pom.xml
+++ b/plugins/host-allocators/random/pom.xml
@@ -23,7 +23,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack-plugins</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../../pom.xml</relativePath>
   </parent>
 </project>
diff --git a/plugins/hypervisors/baremetal/pom.xml b/plugins/hypervisors/baremetal/pom.xml
index 3cc9837..43c806e 100755
--- a/plugins/hypervisors/baremetal/pom.xml
+++ b/plugins/hypervisors/baremetal/pom.xml
@@ -21,7 +21,7 @@
   <parent>

     <groupId>org.apache.cloudstack</groupId>

     <artifactId>cloudstack-plugins</artifactId>

-    <version>4.9.2.0-SNAPSHOT</version>

+    <version>4.9.3.0-SNAPSHOT</version>

     <relativePath>../../pom.xml</relativePath>

   </parent>

   <artifactId>cloud-plugin-hypervisor-baremetal</artifactId>

diff --git a/plugins/hypervisors/hyperv/pom.xml b/plugins/hypervisors/hyperv/pom.xml
index e112aa5..77eb73f 100644
--- a/plugins/hypervisors/hyperv/pom.xml
+++ b/plugins/hypervisors/hyperv/pom.xml
@@ -23,7 +23,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack-plugins</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../../pom.xml</relativePath>
   </parent>
   <properties>
@@ -96,6 +96,35 @@
             <skipTests>${skipTests}</skipTests>
         </configuration>
       </plugin>
+      <plugin>
+        <artifactId>maven-antrun-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>generate-resource</id>
+            <phase>generate-resources</phase>
+            <goals>
+              <goal>run</goal>
+            </goals>
+            <configuration>
+              <target>
+                <copy overwrite="true"
+                  todir="${basedir}/target/classes">
+                  <fileset dir="${basedir}/conf">
+                    <include name="*.in"/>
+                  </fileset>
+                  <filterchain>
+                    <filterreader
+                      classname="org.apache.tools.ant.filters.ReplaceTokens">
+                      <param type="propertiesfile"
+                        value="${project.basedir}/../../../${cs.replace.properties}" />
+                    </filterreader>
+                  </filterchain>
+                </copy>
+              </target>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
     </plugins>
   </build>
   <profiles>
diff --git a/plugins/hypervisors/kvm/pom.xml b/plugins/hypervisors/kvm/pom.xml
index 5d71602..aa3babb 100644
--- a/plugins/hypervisors/kvm/pom.xml
+++ b/plugins/hypervisors/kvm/pom.xml
@@ -15,7 +15,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack-plugins</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../../pom.xml</relativePath>
   </parent>
   <dependencies>
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java
index 7e2b1bf..c26c3e2 100644
--- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java
+++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java
@@ -1464,7 +1464,7 @@
 
     private String getBroadcastUriFromBridge(final String brName) {
         final String pif = matchPifFileInDirectory(brName);
-        final Pattern pattern = Pattern.compile("(\\D+)(\\d+)(\\D*)(\\d*)");
+        final Pattern pattern = Pattern.compile("(\\D+)(\\d+)(\\D*)(\\d*)(\\D*)(\\d*)");
         final Matcher matcher = pattern.matcher(pif);
         s_logger.debug("getting broadcast uri for pif " + pif + " and bridge " + brName);
         if(matcher.find()) {
@@ -1472,7 +1472,9 @@
                 return BroadcastDomainType.Vxlan.toUri(matcher.group(2)).toString();
             }
             else{
-                if (!matcher.group(4).isEmpty()) {
+                if (!matcher.group(6).isEmpty()) {
+                    return BroadcastDomainType.Vlan.toUri(matcher.group(6)).toString();
+                } else if (!matcher.group(4).isEmpty()) {
                     return BroadcastDomainType.Vlan.toUri(matcher.group(4)).toString();
                 } else {
                     //untagged or not matching (eth|bond|team)#.#
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtSetHostParamsCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtSetHostParamsCommandWrapper.java
new file mode 100644
index 0000000..52dd0e9
--- /dev/null
+++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtSetHostParamsCommandWrapper.java
@@ -0,0 +1,45 @@
+//
+// 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.kvm.resource.wrapper;
+
+import java.util.Map;
+
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.SetHostParamsCommand;
+import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
+import com.cloud.resource.CommandWrapper;
+import com.cloud.resource.ResourceWrapper;
+
+@ResourceWrapper(handles =  SetHostParamsCommand.class)
+public final class LibvirtSetHostParamsCommandWrapper extends CommandWrapper<SetHostParamsCommand, Answer, LibvirtComputingResource> {
+
+    @Override
+    public Answer execute(final SetHostParamsCommand command, final LibvirtComputingResource libvirtComputingResource) {
+
+        final Map<String, String> params = command.getParams();
+        boolean success = libvirtComputingResource.getVirtRouterResource().configureHostParams(params);
+
+        if (!success) {
+            return new Answer(command, false, "Failed to set host parameters");
+        } else {
+            return new Answer(command, true, null);
+        }
+    }
+}
diff --git a/plugins/hypervisors/ovm/pom.xml b/plugins/hypervisors/ovm/pom.xml
index 94a34f8..2df95fa 100644
--- a/plugins/hypervisors/ovm/pom.xml
+++ b/plugins/hypervisors/ovm/pom.xml
@@ -23,7 +23,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack-plugins</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../../pom.xml</relativePath>
   </parent>
   <dependencies>
diff --git a/plugins/hypervisors/ovm3/pom.xml b/plugins/hypervisors/ovm3/pom.xml
index 9960a08..0aa096a 100644
--- a/plugins/hypervisors/ovm3/pom.xml
+++ b/plugins/hypervisors/ovm3/pom.xml
@@ -23,7 +23,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack-plugins</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../../pom.xml</relativePath>
   </parent>
   <dependencies>
diff --git a/plugins/hypervisors/simulator/pom.xml b/plugins/hypervisors/simulator/pom.xml
index 1d8f6ae..472d49c 100644
--- a/plugins/hypervisors/simulator/pom.xml
+++ b/plugins/hypervisors/simulator/pom.xml
@@ -22,7 +22,7 @@
     <parent>
         <groupId>org.apache.cloudstack</groupId>
         <artifactId>cloudstack-plugins</artifactId>
-        <version>4.9.2.0-SNAPSHOT</version>
+        <version>4.9.3.0-SNAPSHOT</version>
         <relativePath>../../pom.xml</relativePath>
     </parent>
     <artifactId>cloud-plugin-hypervisor-simulator</artifactId>
diff --git a/plugins/hypervisors/ucs/pom.xml b/plugins/hypervisors/ucs/pom.xml
index 5051b66..71f72d2 100755
--- a/plugins/hypervisors/ucs/pom.xml
+++ b/plugins/hypervisors/ucs/pom.xml
@@ -15,7 +15,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack-plugins</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../../pom.xml</relativePath>
   </parent>
   <artifactId>cloud-plugin-hypervisor-ucs</artifactId>
diff --git a/plugins/hypervisors/vmware/pom.xml b/plugins/hypervisors/vmware/pom.xml
index 43621ca..914ab64 100644
--- a/plugins/hypervisors/vmware/pom.xml
+++ b/plugins/hypervisors/vmware/pom.xml
@@ -23,7 +23,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack-plugins</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../../pom.xml</relativePath>
   </parent>
   <dependencies>
diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareServerDiscoverer.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareServerDiscoverer.java
index 35063b0..4b2f830 100644
--- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareServerDiscoverer.java
+++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareServerDiscoverer.java
@@ -29,7 +29,6 @@
 
 import org.apache.log4j.Logger;
 
-import com.vmware.vim25.ClusterDasConfigInfo;
 import com.vmware.vim25.ManagedObjectReference;
 
 import org.apache.cloudstack.api.ApiConstants;
@@ -344,8 +343,7 @@
                     return null;
                 } else {
                     ClusterMO clusterMo = new ClusterMO(context, morCluster);
-                    ClusterDasConfigInfo dasConfig = clusterMo.getDasConfig();
-                    if (dasConfig != null && dasConfig.isEnabled() != null && dasConfig.isEnabled().booleanValue()) {
+                    if (clusterMo.isHAEnabled()) {
                         clusterDetails.put("NativeHA", "true");
                         _clusterDetailsDao.persist(clusterId, clusterDetails);
                     }
diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java
index ad4ae26..56ca4ea 100644
--- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java
+++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java
@@ -48,9 +48,9 @@
 import com.google.gson.Gson;
 import com.vmware.vim25.AboutInfo;
 import com.vmware.vim25.BoolPolicy;
-import com.vmware.vim25.ClusterDasConfigInfo;
 import com.vmware.vim25.ComputeResourceSummary;
 import com.vmware.vim25.CustomFieldStringValue;
+import com.vmware.vim25.DasVmPriority;
 import com.vmware.vim25.DVPortConfigInfo;
 import com.vmware.vim25.DVPortConfigSpec;
 import com.vmware.vim25.DatastoreSummary;
@@ -1634,6 +1634,11 @@
                     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() / (1024 * 1024)), getReservedMemoryMb(vmSpec),
@@ -1981,6 +1986,10 @@
                 throw new Exception("Failed to configure VM before start. vmName: " + vmInternalCSName);
             }
 
+            if (vmSpec.getType() == VirtualMachine.Type.DomainRouter) {
+                hyperHost.setRestartPriorityForVM(vmMo, DasVmPriority.HIGH.value());
+            }
+
             //
             // Post Configuration
             //
@@ -4805,8 +4814,7 @@
     private void fillHostDetailsInfo(VmwareContext serviceContext, Map<String, String> details) throws Exception {
         VmwareHypervisorHost hyperHost = getHyperHost(getServiceContext());
 
-        ClusterDasConfigInfo dasConfig = hyperHost.getDasConfig();
-        if (dasConfig != null && dasConfig.isEnabled() != null && dasConfig.isEnabled().booleanValue()) {
+        if (hyperHost.isHAEnabled()) {
             details.put("NativeHA", "true");
         }
     }
diff --git a/plugins/hypervisors/xenserver/pom.xml b/plugins/hypervisors/xenserver/pom.xml
index 3419a61..69c2704 100644
--- a/plugins/hypervisors/xenserver/pom.xml
+++ b/plugins/hypervisors/xenserver/pom.xml
@@ -16,7 +16,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack-plugins</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../../pom.xml</relativePath>
   </parent>
   <dependencies>
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java
index 2865e56..ca8a645 100644
--- a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java
+++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java
@@ -29,6 +29,8 @@
 import java.net.URL;
 import java.net.URLConnection;
 import java.nio.charset.Charset;
+
+import org.apache.commons.collections.MapUtils;
 import org.joda.time.Duration;
 import java.util.ArrayList;
 import java.util.Date;
@@ -1149,8 +1151,8 @@
             vbdr.unpluggable = (volume.getType() == Volume.Type.ROOT) ? false : true;
             vbdr.userdevice = "autodetect";
             final Long deviceId = volume.getDiskSeq();
-            if (deviceId != null && !isDeviceUsed(conn, vm, deviceId)) {
-                vbdr.userdevice = deviceId.toString();
+            if (deviceId != null && (!isDeviceUsed(conn, vm, deviceId) || deviceId > 3)) {
+                    vbdr.userdevice = deviceId.toString();
             }
         }
         final VBD vbd = VBD.create(conn, vbdr);
@@ -1415,6 +1417,10 @@
             vbdr.userdevice = "autodetect";
             vbdr.mode = Types.VbdMode.RW;
             vbdr.type = Types.VbdType.DISK;
+            Long deviceId = volumeTO.getDeviceId();
+            if (deviceId != null && (!isDeviceUsed(conn, vm, deviceId) || deviceId > 3)) {
+                vbdr.userdevice = deviceId.toString();
+            }
             VBD.create(conn, vbdr);
         }
         return vm;
@@ -4350,6 +4356,30 @@
         }
     }
 
+    protected void skipOrRemoveSR(Connection conn, SR sr) {
+        if (sr == null) {
+            return;
+        }
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug(logX(sr, "Removing SR"));
+        }
+        try {
+            Set<VDI> vdis = sr.getVDIs(conn);
+            for (VDI vdi : vdis) {
+                if (MapUtils.isEmpty(vdi.getCurrentOperations(conn))) {
+                    continue;
+                }
+                return;
+            }
+            removeSR(conn, sr);
+            return;
+        } catch (XenAPIException | XmlRpcException e) {
+            s_logger.warn(logX(sr, "Unable to get current opertions " + e.toString()), e);
+        }
+        String msg = "Remove SR failed";
+        s_logger.warn(msg);
+    }
+
     public void removeSR(final Connection conn, final SR sr) {
         if (sr == null) {
             return;
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServerStorageProcessor.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServerStorageProcessor.java
index bcf997f..1144276 100644
--- a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServerStorageProcessor.java
+++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServerStorageProcessor.java
@@ -1199,7 +1199,7 @@
             final Set<VDI> snapshots = volume.getSnapshots(conn);
             for (final VDI snapshot : snapshots) {
                 try {
-                    if (!snapshot.getUuid(conn).equals(avoidSnapshotUuid) && snapshot.getSnapshotTime(conn).before(avoidSnapshot.getSnapshotTime(conn))) {
+                    if (!snapshot.getUuid(conn).equals(avoidSnapshotUuid) && snapshot.getSnapshotTime(conn).before(avoidSnapshot.getSnapshotTime(conn)) && snapshot.getVBDs(conn).isEmpty()) {
                         snapshot.destroy(conn);
                     }
                 } catch (final Exception e) {
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/Xenserver625StorageProcessor.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/Xenserver625StorageProcessor.java
index e3c3beb..b70057d 100644
--- a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/Xenserver625StorageProcessor.java
+++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/Xenserver625StorageProcessor.java
@@ -738,7 +738,7 @@
             s_logger.warn(details, e);
         } finally {
             if (srcSr != null) {
-                hypervisorResource.removeSR(conn, srcSr);
+                hypervisorResource.skipOrRemoveSR(conn, srcSr);
             }
             if (!result && destVdi != null) {
                 try {
diff --git a/plugins/metrics/pom.xml b/plugins/metrics/pom.xml
new file mode 100644
index 0000000..946b235
--- /dev/null
+++ b/plugins/metrics/pom.xml
@@ -0,0 +1,55 @@
+<!--
+  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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
+  http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <artifactId>cloud-plugin-metrics</artifactId>
+  <name>Apache CloudStack Plugin - Metrics</name>
+  <parent>
+    <groupId>org.apache.cloudstack</groupId>
+    <artifactId>cloudstack-plugins</artifactId>
+    <version>4.9.3.0-SNAPSHOT</version>
+    <relativePath>../pom.xml</relativePath>
+  </parent>
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.cloudstack</groupId>
+      <artifactId>cloud-api</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.cloudstack</groupId>
+      <artifactId>cloud-utils</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+  </dependencies>
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-surefire-plugin</artifactId>
+        <configuration>
+          <argLine>-Xmx1024m</argLine>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+</project>
diff --git a/plugins/metrics/resources/META-INF/cloudstack/metrics/module.properties b/plugins/metrics/resources/META-INF/cloudstack/metrics/module.properties
new file mode 100644
index 0000000..149b83a
--- /dev/null
+++ b/plugins/metrics/resources/META-INF/cloudstack/metrics/module.properties
@@ -0,0 +1,18 @@
+# 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.
+name=metrics
+parent=api
diff --git a/plugins/metrics/resources/META-INF/cloudstack/metrics/spring-metrics-context.xml b/plugins/metrics/resources/META-INF/cloudstack/metrics/spring-metrics-context.xml
new file mode 100644
index 0000000..6584641
--- /dev/null
+++ b/plugins/metrics/resources/META-INF/cloudstack/metrics/spring-metrics-context.xml
@@ -0,0 +1,27 @@
+<!--
+  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.
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="http://www.springframework.org/schema/beans
+                      http://www.springframework.org/schema/beans/spring-beans.xsd"
+>
+
+    <bean id="metricsService" class="org.apache.cloudstack.metrics.MetricsServiceImpl" >
+    </bean>
+</beans>
diff --git a/plugins/metrics/src/org/apache/cloudstack/api/ListClustersMetricsCmd.java b/plugins/metrics/src/org/apache/cloudstack/api/ListClustersMetricsCmd.java
new file mode 100644
index 0000000..ef259e1
--- /dev/null
+++ b/plugins/metrics/src/org/apache/cloudstack/api/ListClustersMetricsCmd.java
@@ -0,0 +1,51 @@
+// 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;
+
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.api.command.admin.cluster.ListClustersCmd;
+import org.apache.cloudstack.api.response.ListResponse;
+import org.apache.cloudstack.metrics.MetricsService;
+import org.apache.cloudstack.response.ClusterMetricsResponse;
+
+import javax.inject.Inject;
+import java.util.List;
+
+@APICommand(name = ListClustersMetricsCmd.APINAME, description = "Lists clusters metrics", responseObject = ClusterMetricsResponse.class,
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false,  responseView = ResponseObject.ResponseView.Full,
+        since = "4.9.3", authorized = {RoleType.Admin})
+public class ListClustersMetricsCmd extends ListClustersCmd {
+    public static final String APINAME = "listClustersMetrics";
+
+    @Inject
+    private MetricsService metricsService;
+
+    @Override
+    public String getCommandName() {
+        return APINAME.toLowerCase() + BaseCmd.RESPONSE_SUFFIX;
+    }
+
+    @Override
+    public void execute() {
+        final List<ClusterMetricsResponse> metricsResponses = metricsService.listClusterMetrics(getClusterResponses());
+        ListResponse<ClusterMetricsResponse> response = new ListResponse<>();
+        response.setResponses(metricsResponses, metricsResponses.size());
+        response.setResponseName(getCommandName());
+        setResponseObject(response);
+    }
+}
diff --git a/plugins/metrics/src/org/apache/cloudstack/api/ListHostsMetricsCmd.java b/plugins/metrics/src/org/apache/cloudstack/api/ListHostsMetricsCmd.java
new file mode 100644
index 0000000..9010063
--- /dev/null
+++ b/plugins/metrics/src/org/apache/cloudstack/api/ListHostsMetricsCmd.java
@@ -0,0 +1,54 @@
+// 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;
+
+
+import com.cloud.host.Host;
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.api.command.admin.host.ListHostsCmd;
+import org.apache.cloudstack.api.response.ListResponse;
+import org.apache.cloudstack.metrics.MetricsService;
+import org.apache.cloudstack.response.HostMetricsResponse;
+
+import javax.inject.Inject;
+import java.util.List;
+
+@APICommand(name = ListHostsMetricsCmd.APINAME, description = "Lists hosts metrics", responseObject = HostMetricsResponse.class,
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false,  responseView = ResponseObject.ResponseView.Full,
+        since = "4.9.3", authorized = {RoleType.Admin})
+public class ListHostsMetricsCmd extends ListHostsCmd {
+    public static final String APINAME = "listHostsMetrics";
+
+    @Inject
+    private MetricsService metricsService;
+
+    @Override
+    public String getCommandName() {
+        return APINAME.toLowerCase() + BaseCmd.RESPONSE_SUFFIX;
+    }
+
+    @Override
+    public void execute() {
+        setType(Host.Type.Routing.toString());
+        final List<HostMetricsResponse> metricsResponses = metricsService.listHostMetrics(getHostResponses().getResponses());
+        ListResponse<HostMetricsResponse> response = new ListResponse<>();
+        response.setResponses(metricsResponses, metricsResponses.size());
+        response.setResponseName(getCommandName());
+        setResponseObject(response);
+    }
+}
diff --git a/plugins/metrics/src/org/apache/cloudstack/api/ListInfrastructureCmd.java b/plugins/metrics/src/org/apache/cloudstack/api/ListInfrastructureCmd.java
new file mode 100644
index 0000000..4ea24c3
--- /dev/null
+++ b/plugins/metrics/src/org/apache/cloudstack/api/ListInfrastructureCmd.java
@@ -0,0 +1,52 @@
+// 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;
+
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.context.CallContext;
+import org.apache.cloudstack.metrics.MetricsService;
+import org.apache.cloudstack.response.InfrastructureResponse;
+
+import javax.inject.Inject;
+
+@APICommand(name = ListInfrastructureCmd.APINAME, description = "Lists infrastructure", responseObject = InfrastructureResponse.class,
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false,  responseView = ResponseObject.ResponseView.Full,
+        since = "4.9.3", authorized = {RoleType.Admin})
+public class ListInfrastructureCmd extends BaseCmd {
+    public static final String APINAME = "listInfrastructure";
+
+    @Inject
+    private MetricsService metricsService;
+
+    @Override
+    public String getCommandName() {
+        return APINAME.toLowerCase() + BaseCmd.RESPONSE_SUFFIX;
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        return CallContext.current().getCallingAccountId();
+    }
+
+    @Override
+    public void execute() {
+        final InfrastructureResponse response = metricsService.listInfrastructure();
+        response.setResponseName(getCommandName());
+        setResponseObject(response);
+    }
+}
diff --git a/plugins/metrics/src/org/apache/cloudstack/api/ListStoragePoolsMetricsCmd.java b/plugins/metrics/src/org/apache/cloudstack/api/ListStoragePoolsMetricsCmd.java
new file mode 100644
index 0000000..4206568
--- /dev/null
+++ b/plugins/metrics/src/org/apache/cloudstack/api/ListStoragePoolsMetricsCmd.java
@@ -0,0 +1,52 @@
+// 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;
+
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.api.command.admin.storage.ListStoragePoolsCmd;
+import org.apache.cloudstack.api.response.ListResponse;
+import org.apache.cloudstack.metrics.MetricsService;
+import org.apache.cloudstack.response.StoragePoolMetricsResponse;
+
+import javax.inject.Inject;
+import java.util.List;
+
+@APICommand(name = ListStoragePoolsMetricsCmd.APINAME, description = "Lists storage pool metrics", responseObject = StoragePoolMetricsResponse.class,
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false,  responseView = ResponseObject.ResponseView.Full,
+        since = "4.9.3", authorized = {RoleType.Admin})
+public class ListStoragePoolsMetricsCmd extends ListStoragePoolsCmd {
+    public static final String APINAME = "listStoragePoolsMetrics";
+
+    @Inject
+    private MetricsService metricsService;
+
+    @Override
+    public String getCommandName() {
+        return APINAME.toLowerCase() + BaseCmd.RESPONSE_SUFFIX;
+    }
+
+    @Override
+    public void execute() {
+        final List<StoragePoolMetricsResponse> metricsResponses = metricsService.listStoragePoolMetrics(_queryService.searchForStoragePools(this).getResponses());
+        ListResponse<StoragePoolMetricsResponse> response = new ListResponse<>();
+        response.setResponses(metricsResponses, metricsResponses.size());
+        response.setResponseName(getCommandName());
+        setResponseObject(response);
+    }
+
+}
diff --git a/plugins/metrics/src/org/apache/cloudstack/api/ListVMsMetricsCmd.java b/plugins/metrics/src/org/apache/cloudstack/api/ListVMsMetricsCmd.java
new file mode 100644
index 0000000..2321f51
--- /dev/null
+++ b/plugins/metrics/src/org/apache/cloudstack/api/ListVMsMetricsCmd.java
@@ -0,0 +1,51 @@
+// 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;
+
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.api.command.admin.vm.ListVMsCmdByAdmin;
+import org.apache.cloudstack.api.response.ListResponse;
+import org.apache.cloudstack.metrics.MetricsService;
+import org.apache.cloudstack.response.VmMetricsResponse;
+
+import javax.inject.Inject;
+import java.util.List;
+
+@APICommand(name = ListVMsMetricsCmd.APINAME, description = "Lists VM metrics", responseObject = VmMetricsResponse.class,
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false,  responseView = ResponseObject.ResponseView.Full,
+        since = "4.9.3", authorized = {RoleType.Admin,  RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
+public class ListVMsMetricsCmd extends ListVMsCmdByAdmin {
+    public static final String APINAME = "listVirtualMachinesMetrics";
+
+    @Inject
+    private MetricsService metricsService;
+
+    @Override
+    public String getCommandName() {
+        return APINAME.toLowerCase() + BaseCmd.RESPONSE_SUFFIX;
+    }
+
+    @Override
+    public void execute() {
+        final List<VmMetricsResponse> metricsResponses = metricsService.listVmMetrics(_queryService.searchForUserVMs(this).getResponses());
+        ListResponse<VmMetricsResponse> response = new ListResponse<>();
+        response.setResponses(metricsResponses, metricsResponses.size());
+        response.setResponseName(getCommandName());
+        setResponseObject(response);
+    }
+}
diff --git a/plugins/metrics/src/org/apache/cloudstack/api/ListVolumesMetricsCmd.java b/plugins/metrics/src/org/apache/cloudstack/api/ListVolumesMetricsCmd.java
new file mode 100644
index 0000000..54ac922
--- /dev/null
+++ b/plugins/metrics/src/org/apache/cloudstack/api/ListVolumesMetricsCmd.java
@@ -0,0 +1,51 @@
+// 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;
+
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.api.command.admin.volume.ListVolumesCmdByAdmin;
+import org.apache.cloudstack.api.response.ListResponse;
+import org.apache.cloudstack.metrics.MetricsService;
+import org.apache.cloudstack.response.VolumeMetricsResponse;
+
+import javax.inject.Inject;
+import java.util.List;
+
+@APICommand(name = ListVolumesMetricsCmd.APINAME, description = "Lists volume metrics", responseObject = VolumeMetricsResponse.class,
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false,  responseView = ResponseObject.ResponseView.Full,
+        since = "4.9.3", authorized = {RoleType.Admin,  RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
+public class ListVolumesMetricsCmd extends ListVolumesCmdByAdmin {
+    public static final String APINAME = "listVolumesMetrics";
+
+    @Inject
+    private MetricsService metricsService;
+
+    @Override
+    public String getCommandName() {
+        return APINAME.toLowerCase() + BaseCmd.RESPONSE_SUFFIX;
+    }
+
+    @Override
+    public void execute()  {
+        final List<VolumeMetricsResponse> metricsResponses = metricsService.listVolumeMetrics(_queryService.searchForVolumes(this).getResponses());
+        ListResponse<VolumeMetricsResponse> response = new ListResponse<>();
+        response.setResponses(metricsResponses, metricsResponses.size());
+        response.setResponseName(getCommandName());
+        setResponseObject(response);
+    }
+}
diff --git a/plugins/metrics/src/org/apache/cloudstack/api/ListZonesMetricsCmd.java b/plugins/metrics/src/org/apache/cloudstack/api/ListZonesMetricsCmd.java
new file mode 100644
index 0000000..1a51a5f
--- /dev/null
+++ b/plugins/metrics/src/org/apache/cloudstack/api/ListZonesMetricsCmd.java
@@ -0,0 +1,52 @@
+// 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;
+
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.api.command.user.zone.ListZonesCmd;
+import org.apache.cloudstack.api.response.ListResponse;
+import org.apache.cloudstack.metrics.MetricsService;
+import org.apache.cloudstack.response.ZoneMetricsResponse;
+
+import javax.inject.Inject;
+import java.util.List;
+
+@APICommand(name = ListZonesMetricsCmd.APINAME, description = "Lists zone metrics", responseObject = ZoneMetricsResponse.class,
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false,  responseView = ResponseObject.ResponseView.Full,
+        since = "4.9.3", authorized = {RoleType.Admin})
+public class ListZonesMetricsCmd extends ListZonesCmd {
+    public static final String APINAME = "listZonesMetrics";
+
+    @Inject
+    private MetricsService metricsService;
+
+    @Override
+    public String getCommandName() {
+        return APINAME.toLowerCase() + BaseCmd.RESPONSE_SUFFIX;
+    }
+
+    @Override
+    public void execute() {
+        final List<ZoneMetricsResponse> metricsResponses = metricsService.listZoneMetrics(_queryService.listDataCenters(this).getResponses());
+        ListResponse<ZoneMetricsResponse> response = new ListResponse<>();
+        response.setResponses(metricsResponses, metricsResponses.size());
+        response.setResponseName(getCommandName());
+        setResponseObject(response);
+    }
+
+}
diff --git a/plugins/metrics/src/org/apache/cloudstack/metrics/MetricsService.java b/plugins/metrics/src/org/apache/cloudstack/metrics/MetricsService.java
new file mode 100644
index 0000000..deb1da8
--- /dev/null
+++ b/plugins/metrics/src/org/apache/cloudstack/metrics/MetricsService.java
@@ -0,0 +1,46 @@
+// 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.metrics;
+
+import com.cloud.utils.component.PluggableService;
+import org.apache.cloudstack.api.response.ClusterResponse;
+import org.apache.cloudstack.api.response.HostResponse;
+import org.apache.cloudstack.api.response.StoragePoolResponse;
+import org.apache.cloudstack.api.response.UserVmResponse;
+import org.apache.cloudstack.api.response.VolumeResponse;
+import org.apache.cloudstack.api.response.ZoneResponse;
+import org.apache.cloudstack.response.ClusterMetricsResponse;
+import org.apache.cloudstack.response.HostMetricsResponse;
+import org.apache.cloudstack.response.InfrastructureResponse;
+import org.apache.cloudstack.response.StoragePoolMetricsResponse;
+import org.apache.cloudstack.response.VmMetricsResponse;
+import org.apache.cloudstack.response.VolumeMetricsResponse;
+import org.apache.cloudstack.response.ZoneMetricsResponse;
+
+import java.util.List;
+
+public interface MetricsService extends PluggableService {
+    InfrastructureResponse listInfrastructure();
+
+    List<VolumeMetricsResponse> listVolumeMetrics(List<VolumeResponse> volumeResponses);
+    List<VmMetricsResponse> listVmMetrics(List<UserVmResponse> vmResponses);
+    List<StoragePoolMetricsResponse> listStoragePoolMetrics(List<StoragePoolResponse> poolResponses);
+    List<HostMetricsResponse> listHostMetrics(List<HostResponse> poolResponses);
+    List<ClusterMetricsResponse> listClusterMetrics(List<ClusterResponse> poolResponses);
+    List<ZoneMetricsResponse> listZoneMetrics(List<ZoneResponse> poolResponses);
+}
diff --git a/plugins/metrics/src/org/apache/cloudstack/metrics/MetricsServiceImpl.java b/plugins/metrics/src/org/apache/cloudstack/metrics/MetricsServiceImpl.java
new file mode 100644
index 0000000..5cab7bc
--- /dev/null
+++ b/plugins/metrics/src/org/apache/cloudstack/metrics/MetricsServiceImpl.java
@@ -0,0 +1,563 @@
+// 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.metrics;
+
+import com.cloud.alert.AlertManager;
+import com.cloud.api.ApiDBUtils;
+import com.cloud.api.query.dao.HostJoinDao;
+import com.cloud.api.query.vo.HostJoinVO;
+import com.cloud.capacity.Capacity;
+import com.cloud.capacity.CapacityManager;
+import com.cloud.capacity.dao.CapacityDao;
+import com.cloud.capacity.dao.CapacityDaoImpl;
+import com.cloud.dc.DataCenter;
+import com.cloud.dc.dao.ClusterDao;
+import com.cloud.dc.dao.DataCenterDao;
+import com.cloud.dc.dao.HostPodDao;
+import com.cloud.deploy.DeploymentClusterPlanner;
+import com.cloud.host.Host;
+import com.cloud.host.HostStats;
+import com.cloud.host.Status;
+import com.cloud.host.dao.HostDao;
+import com.cloud.org.Cluster;
+import com.cloud.org.Grouping;
+import com.cloud.org.Managed;
+import com.cloud.utils.component.ComponentLifecycleBase;
+import com.cloud.vm.VMInstanceVO;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.dao.DomainRouterDao;
+import com.cloud.vm.dao.VMInstanceDao;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.ListClustersMetricsCmd;
+import org.apache.cloudstack.api.ListHostsMetricsCmd;
+import org.apache.cloudstack.api.ListInfrastructureCmd;
+import org.apache.cloudstack.api.ListStoragePoolsMetricsCmd;
+import org.apache.cloudstack.api.ListVMsMetricsCmd;
+import org.apache.cloudstack.api.ListVolumesMetricsCmd;
+import org.apache.cloudstack.api.ListZonesMetricsCmd;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.ClusterResponse;
+import org.apache.cloudstack.api.response.HostResponse;
+import org.apache.cloudstack.api.response.StoragePoolResponse;
+import org.apache.cloudstack.api.response.UserVmResponse;
+import org.apache.cloudstack.api.response.VolumeResponse;
+import org.apache.cloudstack.api.response.ZoneResponse;
+import org.apache.cloudstack.response.ClusterMetricsResponse;
+import org.apache.cloudstack.response.HostMetricsResponse;
+import org.apache.cloudstack.response.InfrastructureResponse;
+import org.apache.cloudstack.response.StoragePoolMetricsResponse;
+import org.apache.cloudstack.response.VmMetricsResponse;
+import org.apache.cloudstack.response.VolumeMetricsResponse;
+import org.apache.cloudstack.response.ZoneMetricsResponse;
+import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
+import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
+import org.apache.commons.beanutils.BeanUtils;
+
+import javax.inject.Inject;
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.List;
+
+public class MetricsServiceImpl extends ComponentLifecycleBase implements MetricsService {
+
+    @Inject
+    private DataCenterDao dataCenterDao;
+    @Inject
+    private HostPodDao podDao;
+    @Inject
+    private ClusterDao clusterDao;
+    @Inject
+    private HostDao hostDao;
+    @Inject
+    private HostJoinDao hostJoinDao;
+    @Inject
+    private PrimaryDataStoreDao storagePoolDao;
+    @Inject
+    private ImageStoreDao imageStoreDao;
+    @Inject
+    private VMInstanceDao vmInstanceDao;
+    @Inject
+    private DomainRouterDao domainRouterDao;
+    @Inject
+    private CapacityDao capacityDao;
+
+    protected MetricsServiceImpl() {
+        super();
+    }
+
+    private Double findRatioValue(final String value) {
+        if (value != null) {
+            return Double.valueOf(value);
+        }
+        return 1.0;
+    }
+
+    private void updateHostMetrics(final Metrics metrics, final HostJoinVO host) {
+        metrics.incrTotalHosts();
+        metrics.addCpuAllocated(host.getCpuReservedCapacity() + host.getCpuUsedCapacity());
+        metrics.addMemoryAllocated(host.getMemReservedCapacity() + host.getMemUsedCapacity());
+        final HostStats hostStats = ApiDBUtils.getHostStatistics(host.getId());
+        if (hostStats != null) {
+            metrics.addCpuUsedPercentage(hostStats.getCpuUtilization());
+            metrics.addMemoryUsed((long) hostStats.getUsedMemory());
+            metrics.setMaximumCpuUsage(hostStats.getCpuUtilization());
+            metrics.setMaximumMemoryUsage((long) hostStats.getUsedMemory());
+        }
+    }
+
+    @Override
+    public InfrastructureResponse listInfrastructure() {
+        final InfrastructureResponse response = new InfrastructureResponse();
+        response.setZones(dataCenterDao.listAllZones().size());
+        response.setPods(podDao.listAllPods(null).size());
+        response.setClusters(clusterDao.listAllClusters(null).size());
+        response.setHosts(hostDao.listByType(Host.Type.Routing).size());
+        response.setStoragePools(storagePoolDao.listAll().size());
+        response.setImageStores(imageStoreDao.listImageStores().size());
+        response.setSystemvms(vmInstanceDao.listByTypes(VirtualMachine.Type.ConsoleProxy, VirtualMachine.Type.SecondaryStorageVm).size());
+        response.setRouters(domainRouterDao.listAll().size());
+        int cpuSockets = 0;
+        for (final Host host : hostDao.listByType(Host.Type.Routing)) {
+            if (host.getCpuSockets() != null) {
+                cpuSockets += host.getCpuSockets();
+            }
+        }
+        response.setCpuSockets(cpuSockets);
+        return response;
+    }
+
+    @Override
+    public List<VolumeMetricsResponse> listVolumeMetrics(List<VolumeResponse> volumeResponses) {
+        final List<VolumeMetricsResponse> metricsResponses = new ArrayList<>();
+        for (final VolumeResponse volumeResponse: volumeResponses) {
+            VolumeMetricsResponse metricsResponse = new VolumeMetricsResponse();
+
+            try {
+                BeanUtils.copyProperties(metricsResponse, volumeResponse);
+            } catch (IllegalAccessException | InvocationTargetException e) {
+                throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to generate volume metrics response");
+            }
+
+            metricsResponse.setDiskSizeGB(volumeResponse.getSize());
+            metricsResponse.setStorageType(volumeResponse.getStorageType(), volumeResponse.getVolumeType());
+            metricsResponses.add(metricsResponse);
+        }
+        return metricsResponses;
+    }
+
+    @Override
+    public List<VmMetricsResponse> listVmMetrics(List<UserVmResponse> vmResponses) {
+        final List<VmMetricsResponse> metricsResponses = new ArrayList<>();
+        for (final UserVmResponse vmResponse: vmResponses) {
+            VmMetricsResponse metricsResponse = new VmMetricsResponse();
+
+            try {
+                BeanUtils.copyProperties(metricsResponse, vmResponse);
+            } catch (IllegalAccessException | InvocationTargetException e) {
+                throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to generate vm metrics response");
+            }
+
+            metricsResponse.setIpAddress(vmResponse.getNics());
+            metricsResponse.setCpuTotal(vmResponse.getCpuNumber(), vmResponse.getCpuSpeed());
+            metricsResponse.setMemTotal(vmResponse.getMemory());
+            metricsResponse.setNetworkRead(vmResponse.getNetworkKbsRead());
+            metricsResponse.setNetworkWrite(vmResponse.getNetworkKbsWrite());
+            metricsResponse.setDiskRead(vmResponse.getDiskKbsRead());
+            metricsResponse.setDiskWrite(vmResponse.getDiskKbsWrite());
+            metricsResponse.setDiskIopsTotal(vmResponse.getDiskIORead(), vmResponse.getDiskIOWrite());
+            metricsResponses.add(metricsResponse);
+        }
+        return metricsResponses;
+    }
+
+    @Override
+    public List<StoragePoolMetricsResponse> listStoragePoolMetrics(List<StoragePoolResponse> poolResponses) {
+        final List<StoragePoolMetricsResponse> metricsResponses = new ArrayList<>();
+        for (final StoragePoolResponse poolResponse: poolResponses) {
+            StoragePoolMetricsResponse metricsResponse = new StoragePoolMetricsResponse();
+
+            try {
+                BeanUtils.copyProperties(metricsResponse, poolResponse);
+            } catch (IllegalAccessException | InvocationTargetException e) {
+                throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to generate storagepool metrics response");
+            }
+
+            Long poolClusterId = null;
+            final Cluster cluster = clusterDao.findByUuid(poolResponse.getClusterId());
+            if (cluster != null) {
+                poolClusterId = cluster.getId();
+            }
+            final Double storageThreshold = AlertManager.StorageCapacityThreshold.valueIn(poolClusterId);
+            final Double storageDisableThreshold = CapacityManager.StorageCapacityDisableThreshold.valueIn(poolClusterId);
+
+            metricsResponse.setDiskSizeUsedGB(poolResponse.getDiskSizeUsed());
+            metricsResponse.setDiskSizeTotalGB(poolResponse.getDiskSizeTotal(), poolResponse.getOverProvisionFactor());
+            metricsResponse.setDiskSizeAllocatedGB(poolResponse.getDiskSizeAllocated());
+            metricsResponse.setDiskSizeUnallocatedGB(poolResponse.getDiskSizeTotal(), poolResponse.getDiskSizeAllocated(), poolResponse.getOverProvisionFactor());
+            metricsResponse.setStorageUsedThreshold(poolResponse.getDiskSizeTotal(), poolResponse.getDiskSizeUsed(), poolResponse.getOverProvisionFactor(), storageThreshold);
+            metricsResponse.setStorageUsedDisableThreshold(poolResponse.getDiskSizeTotal(), poolResponse.getDiskSizeUsed(), poolResponse.getOverProvisionFactor(), storageDisableThreshold);
+            metricsResponse.setStorageAllocatedThreshold(poolResponse.getDiskSizeTotal(), poolResponse.getDiskSizeAllocated(), poolResponse.getOverProvisionFactor(), storageThreshold);
+            metricsResponse.setStorageAllocatedDisableThreshold(poolResponse.getDiskSizeTotal(), poolResponse.getDiskSizeUsed(), poolResponse.getOverProvisionFactor(), storageDisableThreshold);
+            metricsResponses.add(metricsResponse);
+        }
+        return metricsResponses;
+    }
+
+    @Override
+    public List<HostMetricsResponse> listHostMetrics(List<HostResponse> hostResponses) {
+        final List<HostMetricsResponse> metricsResponses = new ArrayList<>();
+        for (final HostResponse hostResponse: hostResponses) {
+            HostMetricsResponse metricsResponse = new HostMetricsResponse();
+
+            try {
+                BeanUtils.copyProperties(metricsResponse, hostResponse);
+            } catch (IllegalAccessException | InvocationTargetException e) {
+                throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to generate host metrics response");
+            }
+
+            final Host host = hostDao.findByUuid(hostResponse.getId());
+            if (host == null) {
+                continue;
+            }
+            final Long hostId = host.getId();
+            final Long clusterId = host.getClusterId();
+
+            // Thresholds
+            final Double cpuThreshold = AlertManager.CPUCapacityThreshold.valueIn(clusterId);
+            final Double memoryThreshold = AlertManager.MemoryCapacityThreshold.valueIn(clusterId);
+            final Float cpuDisableThreshold = DeploymentClusterPlanner.ClusterCPUCapacityDisableThreshold.valueIn(clusterId);
+            final Float memoryDisableThreshold = DeploymentClusterPlanner.ClusterMemoryCapacityDisableThreshold.valueIn(clusterId);
+            // Over commit ratios
+            final Double cpuOvercommitRatio = findRatioValue(ApiDBUtils.findClusterDetails(clusterId, "cpuOvercommitRatio"));
+            final Double memoryOvercommitRatio = findRatioValue(ApiDBUtils.findClusterDetails(clusterId, "memoryOvercommitRatio"));
+
+            Long upInstances = 0L;
+            Long totalInstances = 0L;
+            for (final VMInstanceVO instance: vmInstanceDao.listByHostId(hostId)) {
+                if (instance == null) {
+                    continue;
+                }
+                if (instance.getType() == VirtualMachine.Type.User) {
+                    totalInstances++;
+                    if (instance.getState() == VirtualMachine.State.Running) {
+                        upInstances++;
+                    }
+                }
+            }
+            metricsResponse.setPowerState(hostResponse.getOutOfBandManagementResponse().getPowerState());
+            metricsResponse.setInstances(upInstances, totalInstances);
+            metricsResponse.setCpuTotal(hostResponse.getCpuNumber(), hostResponse.getCpuSpeed(), cpuOvercommitRatio);
+            metricsResponse.setCpuUsed(hostResponse.getCpuUsed(), hostResponse.getCpuNumber(), hostResponse.getCpuSpeed());
+            metricsResponse.setCpuAllocated(hostResponse.getCpuAllocated(), hostResponse.getCpuNumber(), hostResponse.getCpuSpeed());
+            metricsResponse.setMemTotal(hostResponse.getMemoryTotal(), memoryOvercommitRatio);
+            metricsResponse.setMemAllocated(hostResponse.getMemoryAllocated());
+            metricsResponse.setMemUsed(hostResponse.getMemoryUsed());
+            metricsResponse.setNetworkRead(hostResponse.getNetworkKbsRead());
+            metricsResponse.setNetworkWrite(hostResponse.getNetworkKbsWrite());
+            // CPU thresholds
+            metricsResponse.setCpuUsageThreshold(hostResponse.getCpuUsed(), cpuThreshold);
+            metricsResponse.setCpuUsageDisableThreshold(hostResponse.getCpuUsed(), cpuDisableThreshold);
+            metricsResponse.setCpuAllocatedThreshold(hostResponse.getCpuAllocated(), cpuOvercommitRatio, cpuThreshold);
+            metricsResponse.setCpuAllocatedDisableThreshold(hostResponse.getCpuAllocated(), cpuOvercommitRatio, cpuDisableThreshold);
+            // Memory thresholds
+            metricsResponse.setMemoryUsageThreshold(hostResponse.getMemoryUsed(), hostResponse.getMemoryTotal(), memoryThreshold);
+            metricsResponse.setMemoryUsageDisableThreshold(hostResponse.getMemoryUsed(), hostResponse.getMemoryTotal(), memoryDisableThreshold);
+            metricsResponse.setMemoryAllocatedThreshold(hostResponse.getMemoryAllocated(), hostResponse.getMemoryTotal(), memoryOvercommitRatio, memoryThreshold);
+            metricsResponse.setMemoryAllocatedDisableThreshold(hostResponse.getMemoryAllocated(), hostResponse.getMemoryTotal(), memoryOvercommitRatio, memoryDisableThreshold);
+            metricsResponses.add(metricsResponse);
+        }
+        return metricsResponses;
+    }
+
+    private CapacityDaoImpl.SummedCapacity getCapacity(final int capacityType, final Long zoneId, final Long clusterId) {
+        final List<CapacityDaoImpl.SummedCapacity> capacities = capacityDao.findCapacityBy(capacityType, zoneId, null, clusterId);
+        if (capacities == null || capacities.size() < 1) {
+            return null;
+        }
+        return capacities.get(0);
+    }
+
+    @Override
+    public List<ClusterMetricsResponse> listClusterMetrics(List<ClusterResponse> clusterResponses) {
+        final List<ClusterMetricsResponse> metricsResponses = new ArrayList<>();
+        for (final ClusterResponse clusterResponse: clusterResponses) {
+            ClusterMetricsResponse metricsResponse = new ClusterMetricsResponse();
+
+            try {
+                BeanUtils.copyProperties(metricsResponse, clusterResponse);
+            } catch (IllegalAccessException | InvocationTargetException e) {
+                throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to generate cluster metrics response");
+            }
+
+            final Cluster cluster = clusterDao.findByUuid(clusterResponse.getId());
+            if (cluster == null) {
+                continue;
+            }
+            final Long clusterId = cluster.getId();
+
+            // Thresholds
+            final Double cpuThreshold = AlertManager.CPUCapacityThreshold.valueIn(clusterId);
+            final Double memoryThreshold = AlertManager.MemoryCapacityThreshold.valueIn(clusterId);
+            final Float cpuDisableThreshold = DeploymentClusterPlanner.ClusterCPUCapacityDisableThreshold.valueIn(clusterId);
+            final Float memoryDisableThreshold = DeploymentClusterPlanner.ClusterMemoryCapacityDisableThreshold.valueIn(clusterId);
+
+            final Double cpuOvercommitRatio = findRatioValue(ApiDBUtils.findClusterDetails(clusterId, "cpuOvercommitRatio"));
+            final Double memoryOvercommitRatio = findRatioValue(ApiDBUtils.findClusterDetails(clusterId, "memoryOvercommitRatio"));
+
+            // CPU and memory capacities
+            final CapacityDaoImpl.SummedCapacity cpuCapacity = getCapacity((int) Capacity.CAPACITY_TYPE_CPU, null, clusterId);
+            final CapacityDaoImpl.SummedCapacity memoryCapacity = getCapacity((int) Capacity.CAPACITY_TYPE_MEMORY, null, clusterId);
+            final Metrics metrics = new Metrics(cpuCapacity, memoryCapacity);
+
+            for (final HostJoinVO host: hostJoinDao.findByClusterId(clusterId, Host.Type.Routing)) {
+                if (host.getStatus() == Status.Up) {
+                    metrics.incrUpResources();
+                }
+                metrics.incrTotalResources();
+                updateHostMetrics(metrics, host);
+            }
+
+            metricsResponse.setState(clusterResponse.getAllocationState(), clusterResponse.getManagedState());
+            metricsResponse.setResources(metrics.getUpResources(), metrics.getTotalResources());
+            // CPU
+            metricsResponse.setCpuTotal(metrics.getTotalCpu());
+            metricsResponse.setCpuAllocated(metrics.getCpuAllocated(), metrics.getTotalCpu());
+            if (metrics.getCpuUsedPercentage() > 0L) {
+                metricsResponse.setCpuUsed(metrics.getCpuUsedPercentage(), metrics.getTotalHosts());
+                metricsResponse.setCpuMaxDeviation(metrics.getMaximumCpuUsage(), metrics.getCpuUsedPercentage(), metrics.getTotalHosts());
+            }
+            // Memory
+            metricsResponse.setMemTotal(metrics.getTotalMemory());
+            metricsResponse.setMemAllocated(metrics.getMemoryAllocated(), metrics.getTotalMemory());
+            if (metrics.getMemoryUsed() > 0L) {
+                metricsResponse.setMemUsed(metrics.getMemoryUsed(), metrics.getTotalMemory());
+                metricsResponse.setMemMaxDeviation(metrics.getMaximumMemoryUsage(), metrics.getMemoryUsed(), metrics.getTotalHosts());
+            }
+            // CPU thresholds
+            metricsResponse.setCpuUsageThreshold(metrics.getCpuUsedPercentage(), metrics.getTotalHosts(), cpuThreshold);
+            metricsResponse.setCpuUsageDisableThreshold(metrics.getCpuUsedPercentage(), metrics.getTotalHosts(), cpuDisableThreshold);
+            metricsResponse.setCpuAllocatedThreshold(metrics.getCpuAllocated(), metrics.getTotalCpu(), cpuOvercommitRatio, cpuThreshold);
+            metricsResponse.setCpuAllocatedDisableThreshold(metrics.getCpuAllocated(), metrics.getTotalCpu(), cpuOvercommitRatio, cpuDisableThreshold);
+            // Memory thresholds
+            metricsResponse.setMemoryUsageThreshold(metrics.getMemoryUsed(), metrics.getTotalMemory(), memoryThreshold);
+            metricsResponse.setMemoryUsageDisableThreshold(metrics.getMemoryUsed(), metrics.getTotalMemory(), memoryDisableThreshold);
+            metricsResponse.setMemoryAllocatedThreshold(metrics.getMemoryAllocated(), metrics.getTotalMemory(), memoryOvercommitRatio, memoryThreshold);
+            metricsResponse.setMemoryAllocatedDisableThreshold(metrics.getMemoryAllocated(), metrics.getTotalMemory(), memoryOvercommitRatio, memoryDisableThreshold);
+
+            metricsResponses.add(metricsResponse);
+        }
+        return metricsResponses;
+    }
+
+    @Override
+    public List<ZoneMetricsResponse> listZoneMetrics(List<ZoneResponse> zoneResponses) {
+        final List<ZoneMetricsResponse> metricsResponses = new ArrayList<>();
+        for (final ZoneResponse zoneResponse: zoneResponses) {
+            ZoneMetricsResponse metricsResponse = new ZoneMetricsResponse();
+
+            try {
+                BeanUtils.copyProperties(metricsResponse, zoneResponse);
+            } catch (IllegalAccessException | InvocationTargetException e) {
+                throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to generate zone metrics response");
+            }
+
+            final DataCenter zone = dataCenterDao.findByUuid(zoneResponse.getId());
+            if (zone == null) {
+                continue;
+            }
+            final Long zoneId = zone.getId();
+
+            // Thresholds
+            final Double cpuThreshold = AlertManager.CPUCapacityThreshold.value();
+            final Double memoryThreshold = AlertManager.MemoryCapacityThreshold.value();
+            final Float cpuDisableThreshold = DeploymentClusterPlanner.ClusterCPUCapacityDisableThreshold.value();
+            final Float memoryDisableThreshold = DeploymentClusterPlanner.ClusterMemoryCapacityDisableThreshold.value();
+
+            // CPU and memory capacities
+            final CapacityDaoImpl.SummedCapacity cpuCapacity = getCapacity((int) Capacity.CAPACITY_TYPE_CPU, zoneId, null);
+            final CapacityDaoImpl.SummedCapacity memoryCapacity = getCapacity((int) Capacity.CAPACITY_TYPE_MEMORY, zoneId, null);
+            final Metrics metrics = new Metrics(cpuCapacity, memoryCapacity);
+
+            for (final Cluster cluster : clusterDao.listClustersByDcId(zoneId)) {
+                metrics.incrTotalResources();
+                if (cluster.getAllocationState() == Grouping.AllocationState.Enabled
+                        && cluster.getManagedState() == Managed.ManagedState.Managed) {
+                    metrics.incrUpResources();
+                }
+
+                for (final HostJoinVO host: hostJoinDao.findByClusterId(cluster.getId(), Host.Type.Routing)) {
+                    updateHostMetrics(metrics, host);
+                }
+            }
+
+            metricsResponse.setState(zoneResponse.getAllocationState());
+            metricsResponse.setResource(metrics.getUpResources(), metrics.getTotalResources());
+            // CPU
+            metricsResponse.setCpuTotal(metrics.getTotalCpu());
+            metricsResponse.setCpuAllocated(metrics.getCpuAllocated(), metrics.getTotalCpu());
+            if (metrics.getCpuUsedPercentage() > 0L) {
+                metricsResponse.setCpuUsed(metrics.getCpuUsedPercentage(), metrics.getTotalHosts());
+                metricsResponse.setCpuMaxDeviation(metrics.getMaximumCpuUsage(), metrics.getCpuUsedPercentage(), metrics.getTotalHosts());
+            }
+            // Memory
+            metricsResponse.setMemTotal(metrics.getTotalMemory());
+            metricsResponse.setMemAllocated(metrics.getMemoryAllocated(), metrics.getTotalMemory());
+            if (metrics.getMemoryUsed() > 0L) {
+                metricsResponse.setMemUsed(metrics.getMemoryUsed(), metrics.getTotalMemory());
+                metricsResponse.setMemMaxDeviation(metrics.getMaximumMemoryUsage(), metrics.getMemoryUsed(), metrics.getTotalHosts());
+            }
+            // CPU thresholds
+            metricsResponse.setCpuUsageThreshold(metrics.getCpuUsedPercentage(), metrics.getTotalHosts(), cpuThreshold);
+            metricsResponse.setCpuUsageDisableThreshold(metrics.getCpuUsedPercentage(), metrics.getTotalHosts(), cpuDisableThreshold);
+            metricsResponse.setCpuAllocatedThreshold(metrics.getCpuAllocated(), metrics.getTotalCpu(), cpuThreshold);
+            metricsResponse.setCpuAllocatedDisableThreshold(metrics.getCpuAllocated(), metrics.getTotalCpu(), cpuDisableThreshold);
+            // Memory thresholds
+            metricsResponse.setMemoryUsageThreshold(metrics.getMemoryUsed(), metrics.getTotalMemory(), memoryThreshold);
+            metricsResponse.setMemoryUsageDisableThreshold(metrics.getMemoryUsed(), metrics.getTotalMemory(), memoryDisableThreshold);
+            metricsResponse.setMemoryAllocatedThreshold(metrics.getMemoryAllocated(), metrics.getTotalMemory(), memoryThreshold);
+            metricsResponse.setMemoryAllocatedDisableThreshold(metrics.getMemoryAllocated(), metrics.getTotalMemory(), memoryDisableThreshold);
+
+            metricsResponses.add(metricsResponse);
+        }
+        return metricsResponses;
+    }
+
+    @Override
+    public List<Class<?>> getCommands() {
+        List<Class<?>> cmdList = new ArrayList<Class<?>>();
+        cmdList.add(ListInfrastructureCmd.class);
+        cmdList.add(ListVolumesMetricsCmd.class);
+        cmdList.add(ListVMsMetricsCmd.class);
+        cmdList.add(ListStoragePoolsMetricsCmd.class);
+        cmdList.add(ListHostsMetricsCmd.class);
+        cmdList.add(ListClustersMetricsCmd.class);
+        cmdList.add(ListZonesMetricsCmd.class);
+        return cmdList;
+    }
+
+    private class Metrics {
+        // CPU metrics
+        private Long totalCpu = 0L;
+        private Long cpuAllocated = 0L;
+        private Double cpuUsedPercentage = 0.0;
+        private Double maximumCpuUsage = 0.0;
+        // Memory metrics
+        private Long totalMemory = 0L;
+        private Long memoryUsed = 0L;
+        private Long memoryAllocated = 0L;
+        private Long maximumMemoryUsage = 0L;
+        // Counters
+        private Long totalHosts = 0L;
+        private Long totalResources = 0L;
+        private Long upResources = 0L;
+
+        public Metrics(final CapacityDaoImpl.SummedCapacity totalCpu, final CapacityDaoImpl.SummedCapacity totalMemory) {
+            if (totalCpu != null) {
+                this.totalCpu = totalCpu.getTotalCapacity();
+            }
+            if (totalMemory != null) {
+                this.totalMemory = totalMemory.getTotalCapacity();
+            }
+        }
+
+        public void addCpuAllocated(Long cpuAllocated) {
+            this.cpuAllocated += cpuAllocated;
+        }
+
+        public void addCpuUsedPercentage(Double cpuUsedPercentage) {
+            this.cpuUsedPercentage += cpuUsedPercentage;
+        }
+
+        public void setMaximumCpuUsage(Double maximumCpuUsage) {
+            if (this.maximumCpuUsage == null || (maximumCpuUsage != null && maximumCpuUsage > this.maximumCpuUsage)) {
+                this.maximumCpuUsage = maximumCpuUsage;
+            }
+        }
+
+        public void addMemoryUsed(Long memoryUsed) {
+            this.memoryUsed += memoryUsed;
+        }
+
+        public void addMemoryAllocated(Long memoryAllocated) {
+            this.memoryAllocated += memoryAllocated;
+        }
+
+        public void setMaximumMemoryUsage(Long maximumMemoryUsage) {
+            if (this.maximumMemoryUsage == null || (maximumMemoryUsage != null && maximumMemoryUsage > this.maximumMemoryUsage)) {
+                this.maximumMemoryUsage = maximumMemoryUsage;
+            }
+        }
+
+        public void incrTotalHosts() {
+            this.totalHosts++;
+        }
+
+        public void incrTotalResources() {
+            this.totalResources++;
+        }
+
+        public void incrUpResources() {
+            this.upResources++;
+        }
+
+        public Long getTotalCpu() {
+            return totalCpu;
+        }
+
+        public Long getCpuAllocated() {
+            return cpuAllocated;
+        }
+
+        public Double getCpuUsedPercentage() {
+            return cpuUsedPercentage;
+        }
+
+        public Double getMaximumCpuUsage() {
+            return maximumCpuUsage;
+        }
+
+        public Long getTotalMemory() {
+            return totalMemory;
+        }
+
+        public Long getMemoryUsed() {
+            return memoryUsed;
+        }
+
+        public Long getMemoryAllocated() {
+            return memoryAllocated;
+        }
+
+        public Long getMaximumMemoryUsage() {
+            return maximumMemoryUsage;
+        }
+
+        public Long getTotalHosts() {
+            return totalHosts;
+        }
+
+        public Long getTotalResources() {
+            return totalResources;
+        }
+
+        public Long getUpResources() {
+            return upResources;
+        }
+    }
+
+}
diff --git a/plugins/metrics/src/org/apache/cloudstack/response/ClusterMetricsResponse.java b/plugins/metrics/src/org/apache/cloudstack/response/ClusterMetricsResponse.java
new file mode 100644
index 0000000..d938845
--- /dev/null
+++ b/plugins/metrics/src/org/apache/cloudstack/response/ClusterMetricsResponse.java
@@ -0,0 +1,211 @@
+// 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.response;
+
+import com.cloud.serializer.Param;
+import com.google.gson.annotations.SerializedName;
+import org.apache.cloudstack.api.response.ClusterResponse;
+
+public class ClusterMetricsResponse extends ClusterResponse {
+    @SerializedName("state")
+    @Param(description = "state of the cluster")
+    private String state;
+
+    @SerializedName("hosts")
+    @Param(description = "running / total hosts in the cluster")
+    private String resources;
+
+    @SerializedName("cputotal")
+    @Param(description = "the total cpu capacity in Ghz")
+    private String cpuTotal;
+
+    @SerializedName("cpuused")
+    @Param(description = "the total cpu used in Ghz")
+    private String cpuUsed;
+
+    @SerializedName("cpuallocated")
+    @Param(description = "the total cpu allocated in Ghz")
+    private String cpuAllocated;
+
+    @SerializedName("cpumaxdeviation")
+    @Param(description = "the maximum cpu deviation")
+    private String cpuMaxDeviation;
+
+    @SerializedName("memorytotal")
+    @Param(description = "the total cpu capacity in GiB")
+    private String memTotal;
+
+    @SerializedName("memoryused")
+    @Param(description = "the total cpu used in GiB")
+    private String memUsed;
+
+    @SerializedName("memoryallocated")
+    @Param(description = "the total cpu allocated in GiB")
+    private String memAllocated;
+
+    @SerializedName("memorymaxdeviation")
+    @Param(description = "the maximum memory deviation")
+    private String memMaxDeviation;
+
+    @SerializedName("cputhreshold")
+    @Param(description = "cpu usage notification threshold exceeded")
+    private Boolean cpuThresholdExceeded;
+
+    @SerializedName("cpudisablethreshold")
+    @Param(description = "cpu usage disable threshold exceeded")
+    private Boolean cpuDisableThresholdExceeded;
+
+    @SerializedName("cpuallocatedthreshold")
+    @Param(description = "cpu allocated notification threshold exceeded")
+    private Boolean cpuAllocatedThresholdExceeded;
+
+    @SerializedName("cpuallocateddisablethreshold")
+    @Param(description = "cpu allocated disable threshold exceeded")
+    private Boolean cpuAllocatedDisableThresholdExceeded;
+
+    @SerializedName("memorythreshold")
+    @Param(description = "memory usage notification threshold exceeded")
+    private Boolean memoryThresholdExceeded;
+
+    @SerializedName("memorydisablethreshold")
+    @Param(description = "memory usage disable threshold exceeded")
+    private Boolean memoryDisableThresholdExceeded;
+
+    @SerializedName("memoryallocatedthreshold")
+    @Param(description = "memory allocated notification threshold exceeded")
+    private Boolean memoryAllocatedThresholdExceeded;
+
+    @SerializedName("memoryallocateddisablethreshold")
+    @Param(description = "memory allocated disable threshold exceeded")
+    private Boolean memoryAllocatedDisableThresholdExceeded;
+
+    public void setState(final String allocationState, final String managedState) {
+        this.state = allocationState;
+        if (managedState.equals("Unmanaged")) {
+            this.state = managedState;
+        }
+        if (managedState.equals("Managed")) {
+            this.state = allocationState;
+        }
+    }
+
+    public void setResources(final Long upResources, final Long totalResources) {
+        if (upResources != null && totalResources != null) {
+            this.resources = String.format("%d / %d", upResources, totalResources);
+        }
+    }
+
+    public void setCpuTotal(final Long cpuTotal) {
+        if (cpuTotal != null) {
+            this.cpuTotal = String.format("%.2f Ghz", cpuTotal / 1000.0);
+        }
+    }
+
+    public void setCpuUsed(final Double cpuUsedPercentage, final Long totalHosts) {
+        if (cpuUsedPercentage != null && totalHosts != null && totalHosts != 0) {
+            this.cpuUsed = String.format("%.2f%%", 1.0 * cpuUsedPercentage / totalHosts);
+        }
+    }
+
+    public void setCpuAllocated(final Long cpuAllocated, final Long cpuTotal) {
+        if (cpuAllocated != null && cpuTotal != null && cpuTotal != 0) {
+            this.cpuAllocated = String.format("%.2f%%", cpuAllocated * 100.0 / cpuTotal);
+        }
+    }
+
+    public void setCpuMaxDeviation(final Double maxCpuUsagePercentage, final Double totalCpuUsedPercentage, final Long totalHosts) {
+        if (maxCpuUsagePercentage != null && totalCpuUsedPercentage != null && totalHosts != null && totalHosts != 0) {
+            final Double averageCpuUsagePercentage = totalCpuUsedPercentage / totalHosts;
+            this.cpuMaxDeviation = String.format("%.2f%%", (maxCpuUsagePercentage - averageCpuUsagePercentage) / averageCpuUsagePercentage);
+        }
+    }
+
+    public void setMemTotal(final Long memTotal) {
+        if (memTotal != null) {
+            this.memTotal = String.format("%.2f GB", memTotal / (1024.0 * 1024.0 * 1024.0));
+        }
+    }
+
+    public void setMemUsed( final Long memUsed, final Long memTotal) {
+        if (memUsed != null && memTotal != null && memTotal != 0) {
+            this.memUsed = String.format("%.2f%%", memUsed * 100.0 / memTotal);
+        }
+    }
+
+    public void setMemAllocated(final Long memAllocated, final Long memTotal) {
+        if (memAllocated != null && memTotal != null && memTotal != 0) {
+            this.memAllocated = String.format("%.2f%%", memAllocated * 100.0 / memTotal);
+        }
+    }
+
+    public void setMemMaxDeviation(final Long maxMemoryUsage, final Long totalMemory, final Long totalHosts) {
+        if (maxMemoryUsage != null && totalMemory != null && totalHosts != null && totalHosts != 0) {
+            final Double averageMemoryUsage = 1.0 * totalMemory / totalHosts;
+            this.memMaxDeviation = String.format("%.2f%%", (maxMemoryUsage - averageMemoryUsage) * 100.0 / averageMemoryUsage);
+        }
+    }
+
+    public void setCpuUsageThreshold(final Double cpuUsed, final Long totalHosts, final Double threshold) {
+        if (cpuUsed != null && totalHosts != null && threshold != null && totalHosts != 0) {
+            this.cpuThresholdExceeded = (cpuUsed / (100.0 * totalHosts)) > threshold;
+        }
+    }
+
+    public void setCpuUsageDisableThreshold(final Double cpuUsed, final Long totalHosts, final Float threshold) {
+        if (cpuUsed != null && totalHosts != null && threshold != null && totalHosts != 0) {
+            this.cpuDisableThresholdExceeded = (cpuUsed / (100.0 * totalHosts)) > threshold;
+        }
+    }
+
+    public void setCpuAllocatedThreshold(final Long cpuAllocated, final Long cpuUsed, final Double overCommitRatio, final Double threshold) {
+        if (cpuAllocated != null && cpuUsed != null && overCommitRatio != null && threshold != null && cpuUsed != 0) {
+            this.cpuAllocatedThresholdExceeded = (1.0 * cpuAllocated * overCommitRatio / cpuUsed) > threshold;
+        }
+    }
+
+    public void setCpuAllocatedDisableThreshold(final Long cpuAllocated, final Long cpuUsed, final Double overCommitRatio, final Float threshold) {
+        if (cpuAllocated != null && cpuUsed != null && overCommitRatio != null && threshold != null && cpuUsed != 0) {
+            this.cpuAllocatedDisableThresholdExceeded = (1.0 * cpuAllocated * overCommitRatio / cpuUsed) > threshold;
+        }
+    }
+
+    public void setMemoryUsageThreshold(final Long memUsed, final Long memTotal, final Double threshold) {
+        if (memUsed != null && memTotal != null && threshold != null && memTotal != 0) {
+            this.memoryThresholdExceeded = (1.0 * memUsed / memTotal) > threshold;
+        }
+    }
+
+    public void setMemoryUsageDisableThreshold(final Long memUsed, final Long memTotal, final Float threshold) {
+        if (memUsed != null && memTotal != null && threshold != null && memTotal != 0) {
+            this.memoryDisableThresholdExceeded = (1.0 * memUsed / memTotal) > threshold;
+        }
+    }
+
+
+    public void setMemoryAllocatedThreshold(final Long memAllocated, final Long memTotal, final Double overCommitRatio, final Double threshold) {
+        if (memAllocated != null && memTotal != null && overCommitRatio != null && threshold != null && memTotal != 0) {
+            this.memoryAllocatedThresholdExceeded = (1.0 * memAllocated * overCommitRatio / memTotal) > threshold;
+        }
+    }
+
+    public void setMemoryAllocatedDisableThreshold(final Long memAllocated, final Long memTotal, final Double overCommitRatio, final Float threshold) {
+        if (memAllocated != null && memTotal != null && overCommitRatio != null && threshold != null && memTotal != 0) {
+            this.memoryAllocatedDisableThresholdExceeded = (1.0 * memAllocated * overCommitRatio / memTotal) > threshold;
+        }
+    }
+}
diff --git a/plugins/metrics/src/org/apache/cloudstack/response/HostMetricsResponse.java b/plugins/metrics/src/org/apache/cloudstack/response/HostMetricsResponse.java
new file mode 100644
index 0000000..cdc9d16
--- /dev/null
+++ b/plugins/metrics/src/org/apache/cloudstack/response/HostMetricsResponse.java
@@ -0,0 +1,204 @@
+// 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.response;
+
+import com.cloud.serializer.Param;
+import com.google.gson.annotations.SerializedName;
+import org.apache.cloudstack.api.response.HostResponse;
+import org.apache.cloudstack.outofbandmanagement.OutOfBandManagement;
+
+public class HostMetricsResponse extends HostResponse {
+    @SerializedName("powerstate")
+    @Param(description = "out-of-band management power state")
+    private OutOfBandManagement.PowerState powerState;
+
+    @SerializedName("instances")
+    @Param(description = "instances on the host")
+    private String instances;
+
+    @SerializedName("cputotalghz")
+    @Param(description = "the total cpu capacity in Ghz")
+    private String cpuTotal;
+
+    @SerializedName("cpuusedghz")
+    @Param(description = "the total cpu used in Ghz")
+    private String cpuUsed;
+
+    @SerializedName("cpuallocatedghz")
+    @Param(description = "the total cpu allocated in Ghz")
+    private String cpuAllocated;
+
+    @SerializedName("memorytotalgb")
+    @Param(description = "the total cpu capacity in GiB")
+    private String memTotal;
+
+    @SerializedName("memoryusedgb")
+    @Param(description = "the total cpu used in GiB")
+    private String memUsed;
+
+    @SerializedName("memoryallocatedgb")
+    @Param(description = "the total cpu allocated in GiB")
+    private String memAllocated;
+
+    @SerializedName("networkread")
+    @Param(description = "network read in GiB")
+    private String networkRead;
+
+    @SerializedName("networkwrite")
+    @Param(description = "network write in GiB")
+    private String networkWrite;
+
+    @SerializedName("cputhreshold")
+    @Param(description = "cpu usage notification threshold exceeded")
+    private Boolean cpuThresholdExceeded;
+
+    @SerializedName("cpudisablethreshold")
+    @Param(description = "cpu usage disable threshold exceeded")
+    private Boolean cpuDisableThresholdExceeded;
+
+    @SerializedName("cpuallocatedthreshold")
+    @Param(description = "cpu allocated notification threshold exceeded")
+    private Boolean cpuAllocatedThresholdExceeded;
+
+    @SerializedName("cpuallocateddisablethreshold")
+    @Param(description = "cpu allocated disable threshold exceeded")
+    private Boolean cpuAllocatedDisableThresholdExceeded;
+
+    @SerializedName("memorythreshold")
+    @Param(description = "memory usage notification threshold exceeded")
+    private Boolean memoryThresholdExceeded;
+
+    @SerializedName("memorydisablethreshold")
+    @Param(description = "memory usage disable threshold exceeded")
+    private Boolean memoryDisableThresholdExceeded;
+
+    @SerializedName("memoryallocatedthreshold")
+    @Param(description = "memory allocated notification threshold exceeded")
+    private Boolean memoryAllocatedThresholdExceeded;
+
+    @SerializedName("memoryallocateddisablethreshold")
+    @Param(description = "memory allocated disable threshold exceeded")
+    private Boolean memoryAllocatedDisableThresholdExceeded;
+
+    public void setPowerState(final OutOfBandManagement.PowerState powerState) {
+        this.powerState = powerState;
+    }
+
+    public void setInstances(final Long running, final Long total) {
+        if (running != null && total != null) {
+            this.instances = String.format("%d / %d", running, total);
+        }
+    }
+
+    public void setCpuTotal(final Integer cpuNumber, final Long cpuSpeed, final Double overcommitRatio) {
+        if (cpuNumber != null && cpuSpeed != null && overcommitRatio != null) {
+            this.cpuTotal = String.format("%.2f Ghz (x %.1f)", cpuNumber * cpuSpeed / 1000.0, overcommitRatio);
+        }
+    }
+
+    public void setCpuUsed(final String cpuUsed, final Integer cpuNumber, final Long cpuSpeed) {
+        if (cpuUsed != null && cpuNumber != null && cpuSpeed != null) {
+            this.cpuUsed = String.format("%.2f Ghz", Double.valueOf(cpuUsed.replace("%", "")) * cpuNumber * cpuSpeed / (100.0 * 1000.0));
+        }
+    }
+
+    public void setCpuAllocated(final String cpuAllocated, final Integer cpuNumber, final Long cpuSpeed) {
+        if (cpuAllocated != null && cpuNumber != null && cpuSpeed != null) {
+            this.cpuAllocated = String.format("%.2f Ghz", Double.valueOf(cpuAllocated.replace("%", "")) * cpuNumber * cpuSpeed / (100.0 * 1000.0));
+        }
+    }
+
+    public void setMemTotal(final Long memTotal, final Double overcommitRatio) {
+        if (memTotal != null && overcommitRatio != null) {
+            this.memTotal = String.format("%.2f GB (x %.1f)", memTotal / (1024.0 * 1024.0 * 1024.0), overcommitRatio);
+        }
+    }
+
+    public void setMemUsed(final Long memUsed) {
+        if (memUsed != null) {
+            this.memUsed = String.format("%.2f GB", memUsed / (1024.0 * 1024.0 * 1024.0));
+        }
+    }
+
+    public void setMemAllocated(final Long memAllocated) {
+        if (memAllocated != null) {
+            this.memAllocated = String.format("%.2f GB", memAllocated / (1024.0 * 1024.0 * 1024.0));
+        }
+    }
+
+    public void setNetworkRead(final Long networkReadKbs) {
+        if (networkReadKbs != null) {
+            this.networkRead = String.format("%.2f GB", networkReadKbs / (1024.0 * 1024.0));
+        }
+    }
+
+    public void setNetworkWrite(final Long networkWriteKbs) {
+        if (networkWriteKbs != null) {
+            this.networkWrite = String.format("%.2f GB", networkWriteKbs / (1024.0 * 1024.0));
+        }
+    }
+
+    public void setCpuUsageThreshold(final String cpuUsed, final Double threshold) {
+        if (cpuUsed != null && threshold != null) {
+            this.cpuThresholdExceeded = Double.valueOf(cpuUsed.replace("%", "")) > (100.0 * threshold);
+        }
+    }
+
+    public void setCpuUsageDisableThreshold(final String cpuUsed, final Float threshold) {
+        if (cpuUsed != null && threshold != null) {
+            this.cpuDisableThresholdExceeded = Double.valueOf(cpuUsed.replace("%", "")) > (100.0 * threshold);
+        }
+    }
+
+    public void setCpuAllocatedThreshold(final String cpuAllocated, final Double overCommitRatio, final Double threshold) {
+        if (cpuAllocated != null && overCommitRatio != null && threshold != null) {
+            this.cpuAllocatedThresholdExceeded = (Double.valueOf(cpuAllocated.replace("%", "")) * overCommitRatio) > (100.0 * threshold);
+        }
+    }
+
+    public void setCpuAllocatedDisableThreshold(final String cpuAllocated, final Double overCommitRatio, final Float threshold) {
+        if (cpuAllocated != null && overCommitRatio != null && threshold != null) {
+            this.cpuAllocatedDisableThresholdExceeded = (Double.valueOf(cpuAllocated.replace("%", "")) * overCommitRatio) > (100.0 * threshold);
+        }
+    }
+
+    public void setMemoryUsageThreshold(final Long memUsed, final Long memTotal, final Double threshold) {
+        if (memUsed != null && memTotal != null && threshold != null) {
+            this.memoryThresholdExceeded = memUsed > (memTotal * threshold);
+        }
+    }
+
+    public void setMemoryUsageDisableThreshold(final Long memUsed, final Long memTotal, final Float threshold) {
+        if (memUsed != null && memTotal != null && threshold != null) {
+            this.memoryDisableThresholdExceeded = memUsed > (memTotal * threshold);
+        }
+    }
+
+    public void setMemoryAllocatedThreshold(final Long memAllocated, final Long memTotal, final Double overCommitRatio, final Double threshold) {
+        if (memAllocated != null && memTotal != null && overCommitRatio != null && threshold != null) {
+            this.memoryAllocatedThresholdExceeded = (memAllocated * overCommitRatio) > (memTotal * threshold);
+        }
+    }
+
+    public void setMemoryAllocatedDisableThreshold(final Long memAllocated, final Long memTotal, final Double overCommitRatio, final Float threshold) {
+        if (memAllocated != null && memTotal != null && overCommitRatio != null && threshold != null) {
+            this.memoryAllocatedDisableThresholdExceeded = (memAllocated * overCommitRatio) > (memTotal * threshold);
+        }
+    }
+
+}
diff --git a/plugins/metrics/src/org/apache/cloudstack/response/InfrastructureResponse.java b/plugins/metrics/src/org/apache/cloudstack/response/InfrastructureResponse.java
new file mode 100644
index 0000000..a4db345
--- /dev/null
+++ b/plugins/metrics/src/org/apache/cloudstack/response/InfrastructureResponse.java
@@ -0,0 +1,101 @@
+// 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.response;
+
+import com.cloud.serializer.Param;
+import com.google.gson.annotations.SerializedName;
+import org.apache.cloudstack.api.BaseResponse;
+
+public class InfrastructureResponse extends BaseResponse {
+
+    @SerializedName("zones")
+    @Param(description = "Number of zones")
+    private Integer zones;
+
+    @SerializedName("pods")
+    @Param(description = "Number of pods")
+    private Integer pods;
+
+    @SerializedName("clusters")
+    @Param(description = "Number of clusters")
+    private Integer clusters;
+
+    @SerializedName("hosts")
+    @Param(description = "Number of hypervisor hosts")
+    private Integer hosts;
+
+    @SerializedName("storagepools")
+    @Param(description = "Number of storage pools")
+    private Integer storagePools;
+
+    @SerializedName("imagestores")
+    @Param(description = "Number of images stores")
+    private Integer imageStores;
+
+    @SerializedName("systemvms")
+    @Param(description = "Number of systemvms")
+    private Integer systemvms;
+
+    @SerializedName("routers")
+    @Param(description = "Number of routers")
+    private Integer routers;
+
+    @SerializedName("cpusockets")
+    @Param(description = "Number of cpu sockets")
+    private Integer cpuSockets;
+
+    public InfrastructureResponse() {
+        setObjectName("infrastructure");
+    }
+
+    public void setZones(final Integer zones) {
+        this.zones = zones;
+    }
+
+    public void setPods(final Integer pods) {
+        this.pods = pods;
+    }
+
+    public void setClusters(final Integer clusters) {
+        this.clusters = clusters;
+    }
+
+    public void setHosts(final Integer hosts) {
+        this.hosts = hosts;
+    }
+
+    public void setStoragePools(final Integer storagePools) {
+        this.storagePools = storagePools;
+    }
+
+    public void setImageStores(final Integer imageStores) {
+        this.imageStores = imageStores;
+    }
+
+    public void setSystemvms(final Integer systemvms) {
+        this.systemvms = systemvms;
+    }
+
+    public void setRouters(final Integer routers) {
+        this.routers = routers;
+    }
+
+    public void setCpuSockets(final Integer cpuSockets) {
+        this.cpuSockets = cpuSockets;
+    }
+}
diff --git a/plugins/metrics/src/org/apache/cloudstack/response/StoragePoolMetricsResponse.java b/plugins/metrics/src/org/apache/cloudstack/response/StoragePoolMetricsResponse.java
new file mode 100644
index 0000000..f20f797
--- /dev/null
+++ b/plugins/metrics/src/org/apache/cloudstack/response/StoragePoolMetricsResponse.java
@@ -0,0 +1,105 @@
+// 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.response;
+
+import com.cloud.serializer.Param;
+import com.google.gson.annotations.SerializedName;
+import org.apache.cloudstack.api.response.StoragePoolResponse;
+
+public class StoragePoolMetricsResponse extends StoragePoolResponse {
+    @SerializedName("disksizeusedgb")
+    @Param(description = "disk size used in GiB")
+    private String diskSizeUsedGB;
+
+    @SerializedName("disksizetotalgb")
+    @Param(description = "disk size in GiB")
+    private String diskSizeTotalGB;
+
+    @SerializedName("disksizeallocatedgb")
+    @Param(description = "disk size allocated in GiB")
+    private String diskSizeAllocatedGB;
+
+    @SerializedName("disksizeunallocatedgb")
+    @Param(description = "disk size unallocated in GiB")
+    private String diskSizeUnallocatedGB;
+
+    @SerializedName("storageusagethreshold")
+    @Param(description = "storage usage notification threshold exceeded")
+    private Boolean storageUsedThreshold;
+
+    @SerializedName("storageusagedisablethreshold")
+    @Param(description = "storage usage disable threshold exceeded")
+    private Boolean storageUsedDisableThreshold;
+
+    @SerializedName("storageallocatedthreshold")
+    @Param(description = "storage allocated notification threshold exceeded")
+    private Boolean storageAllocatedThreshold;
+
+    @SerializedName("storageallocateddisablethreshold")
+    @Param(description = "storage allocated disable threshold exceeded")
+    private Boolean storageAllocatedDisableThreshold;
+
+    public void setDiskSizeUsedGB(final Long diskSizeUsed) {
+        if (diskSizeUsed != null) {
+            this.diskSizeUsedGB = String.format("%.2f GB", diskSizeUsed / (1024.0 * 1024.0 * 1024.0));
+        }
+    }
+
+    public void setDiskSizeTotalGB(final Long totalDiskSize, final String overProvisionFactor) {
+        if (totalDiskSize != null && overProvisionFactor != null) {
+            this.diskSizeTotalGB = String.format("%.2f GB (x%s)", totalDiskSize / (1024.0 * 1024.0 * 1024.0), overProvisionFactor);
+        }
+    }
+
+    public void setDiskSizeAllocatedGB(final Long diskSizeAllocated) {
+        if (diskSizeAllocated != null) {
+            this.diskSizeAllocatedGB = String.format("%.2f GB", diskSizeAllocated / (1024.0 * 1024.0 * 1024.0));
+
+        }
+    }
+
+    public void setDiskSizeUnallocatedGB(final Long totalDiskSize, final Long diskSizeAllocated, final String overProvisionFactor) {
+        if (totalDiskSize != null && diskSizeAllocated != null && overProvisionFactor != null) {
+            this.diskSizeUnallocatedGB = String.format("%.2f GB", ((Double.valueOf(overProvisionFactor) * totalDiskSize) - diskSizeAllocated) / (1024.0 * 1024.0 * 1024.0));
+        }
+    }
+
+    public void setStorageUsedThreshold(final Long totalDiskSize, final Long diskSizeUsed, final String overProvisionFactor, final Double threshold) {
+        if (totalDiskSize != null && diskSizeUsed != null && overProvisionFactor != null && threshold != null) {
+            this.storageUsedThreshold = diskSizeUsed > (totalDiskSize * Double.valueOf(overProvisionFactor) * threshold) ;
+        }
+    }
+
+    public void setStorageUsedDisableThreshold(final Long totalDiskSize, final Long diskSizeUsed, final String overProvisionFactor, final Double threshold) {
+        if (totalDiskSize != null && diskSizeUsed != null && overProvisionFactor != null && threshold != null) {
+            this.storageUsedDisableThreshold = diskSizeUsed > (totalDiskSize * Double.valueOf(overProvisionFactor) * threshold);
+        }
+    }
+
+    public void setStorageAllocatedThreshold(final Long totalDiskSize, final Long diskSizeAllocated, final String overProvisionFactor, final Double threshold) {
+        if (totalDiskSize != null && diskSizeAllocated != null && overProvisionFactor != null && threshold != null) {
+            this.storageAllocatedThreshold = diskSizeAllocated > (totalDiskSize * Double.valueOf(overProvisionFactor) * threshold);
+        }
+    }
+
+    public void setStorageAllocatedDisableThreshold(final Long totalDiskSize, final Long diskSizeAllocated, final String overProvisionFactor, final Double threshold) {
+        if (totalDiskSize != null && diskSizeAllocated != null && overProvisionFactor != null && threshold != null) {
+            this.storageAllocatedDisableThreshold = diskSizeAllocated > (totalDiskSize * Double.valueOf(overProvisionFactor) * threshold);
+        }
+    }
+}
diff --git a/plugins/metrics/src/org/apache/cloudstack/response/VmMetricsResponse.java b/plugins/metrics/src/org/apache/cloudstack/response/VmMetricsResponse.java
new file mode 100644
index 0000000..a4057ae
--- /dev/null
+++ b/plugins/metrics/src/org/apache/cloudstack/response/VmMetricsResponse.java
@@ -0,0 +1,108 @@
+// 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.response;
+
+import com.cloud.serializer.Param;
+import com.google.gson.annotations.SerializedName;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.response.NicResponse;
+import org.apache.cloudstack.api.response.UserVmResponse;
+
+import java.util.Set;
+
+public class VmMetricsResponse extends UserVmResponse {
+    @SerializedName(ApiConstants.IP_ADDRESS)
+    @Param(description = "the VM's primary IP address")
+    private String ipAddress;
+
+    @SerializedName("cputotal")
+    @Param(description = "the total cpu capacity in Ghz")
+    private String cpuTotal;
+
+    @SerializedName("memorytotal")
+    @Param(description = "the total memory capacity in GiB")
+    private String memTotal;
+
+    @SerializedName("networkread")
+    @Param(description = "network read in MiB")
+    private String networkRead;
+
+    @SerializedName("networkwrite")
+    @Param(description = "network write in MiB")
+    private String networkWrite;
+
+    @SerializedName("diskread")
+    @Param(description = "disk read in MiB")
+    private String diskRead;
+
+    @SerializedName("diskwrite")
+    @Param(description = "disk write in MiB")
+    private String diskWrite;
+
+    @SerializedName("diskiopstotal")
+    @Param(description = "the total disk iops")
+    private Long diskIopsTotal;
+
+    public void setIpAddress(final Set<NicResponse> nics) {
+        if (nics != null && nics.size() > 0) {
+            this.ipAddress = nics.iterator().next().getIpaddress();
+        }
+    }
+
+    public void setCpuTotal(final Integer cpuNumber, final Integer cpuSpeed) {
+        if (cpuNumber != null && cpuSpeed != null) {
+            this.cpuTotal = String.format("%.1f Ghz", cpuNumber * cpuSpeed / 1000.0);
+        }
+    }
+
+    public void setMemTotal(final Integer memory) {
+        if (memory != null) {
+            this.memTotal = String.format("%.2f GB", memory / 1024.0);
+        }
+    }
+
+    public void setNetworkRead(final Long networkReadKbs) {
+        if (networkReadKbs != null) {
+            this.networkRead = String.format("%.2f MB", networkReadKbs / 1024.0);
+        }
+    }
+
+    public void setNetworkWrite(final Long networkWriteKbs) {
+        if (networkWriteKbs != null) {
+            this.networkWrite = String.format("%.2f MB", networkWriteKbs / 1024.0);
+        }
+    }
+
+    public void setDiskRead(final Long diskReadKbs) {
+        if (diskReadKbs != null) {
+            this.networkRead = String.format("%.2f MB", diskReadKbs / 1024.0);
+        }
+    }
+
+    public void setDiskWrite(final Long diskWriteKbs) {
+        if (diskWriteKbs != null) {
+            this.networkWrite = String.format("%.2f MB", diskWriteKbs / 1024.0);
+        }
+    }
+
+    public void setDiskIopsTotal(final Long diskIoRead, final Long diskIoWrite) {
+        if (diskIoRead != null && diskIoWrite != null) {
+            this.diskIopsTotal = diskIoRead + diskIoWrite;
+        }
+    }
+}
diff --git a/plugins/metrics/src/org/apache/cloudstack/response/VolumeMetricsResponse.java b/plugins/metrics/src/org/apache/cloudstack/response/VolumeMetricsResponse.java
new file mode 100644
index 0000000..ef8515f
--- /dev/null
+++ b/plugins/metrics/src/org/apache/cloudstack/response/VolumeMetricsResponse.java
@@ -0,0 +1,41 @@
+// 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.response;
+
+import com.cloud.serializer.Param;
+import com.google.common.base.Strings;
+import com.google.gson.annotations.SerializedName;
+import org.apache.cloudstack.api.response.VolumeResponse;
+
+public class VolumeMetricsResponse extends VolumeResponse {
+    @SerializedName("sizegb")
+    @Param(description = "disk size in GiB")
+    private String diskSizeGB;
+
+    public void setStorageType(final String storageType, final String volumeType) {
+        if (!Strings.isNullOrEmpty(storageType) && !Strings.isNullOrEmpty(volumeType)) {
+            this.setStorageType(String.format("%s (%s)", storageType.substring(0, 1).toUpperCase() + storageType.substring(1), volumeType));
+        }
+    }
+
+    public void setDiskSizeGB(final Long size) {
+        if (size != null) {
+            this.diskSizeGB = String.format("%.2f GB", size / (1024.0 * 1024.0 * 1024.0));
+        }
+    }
+}
diff --git a/plugins/metrics/src/org/apache/cloudstack/response/ZoneMetricsResponse.java b/plugins/metrics/src/org/apache/cloudstack/response/ZoneMetricsResponse.java
new file mode 100644
index 0000000..b3c1f86
--- /dev/null
+++ b/plugins/metrics/src/org/apache/cloudstack/response/ZoneMetricsResponse.java
@@ -0,0 +1,206 @@
+// 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.response;
+
+import com.cloud.serializer.Param;
+import com.google.gson.annotations.SerializedName;
+import org.apache.cloudstack.api.response.ZoneResponse;
+
+public class ZoneMetricsResponse extends ZoneResponse {
+    @SerializedName("state")
+    @Param(description = "state of the cluster")
+    private String state;
+
+    @SerializedName("clusters")
+    @Param(description = "healthy / total clusters in the zone")
+    private String resources;
+
+    @SerializedName("cputotal")
+    @Param(description = "the total cpu capacity in Ghz")
+    private String cpuTotal;
+
+    @SerializedName("cpuused")
+    @Param(description = "the total cpu used in Ghz")
+    private String cpuUsed;
+
+    @SerializedName("cpuallocated")
+    @Param(description = "the total cpu allocated in Ghz")
+    private String cpuAllocated;
+
+    @SerializedName("cpumaxdeviation")
+    @Param(description = "the maximum cpu deviation")
+    private String cpuMaxDeviation;
+
+    @SerializedName("memorytotal")
+    @Param(description = "the total cpu capacity in GiB")
+    private String memTotal;
+
+    @SerializedName("memoryused")
+    @Param(description = "the total cpu used in GiB")
+    private String memUsed;
+
+    @SerializedName("memoryallocated")
+    @Param(description = "the total cpu allocated in GiB")
+    private String memAllocated;
+
+    @SerializedName("memorymaxdeviation")
+    @Param(description = "the maximum memory deviation")
+    private String memMaxDeviation;
+
+    @SerializedName("cputhreshold")
+    @Param(description = "cpu usage notification threshold exceeded")
+    private Boolean cpuThresholdExceeded;
+
+    @SerializedName("cpudisablethreshold")
+    @Param(description = "cpu usage disable threshold exceeded")
+    private Boolean cpuDisableThresholdExceeded;
+
+    @SerializedName("cpuallocatedthreshold")
+    @Param(description = "cpu allocated notification threshold exceeded")
+    private Boolean cpuAllocatedThresholdExceeded;
+
+    @SerializedName("cpuallocateddisablethreshold")
+    @Param(description = "cpu allocated disable threshold exceeded")
+    private Boolean cpuAllocatedDisableThresholdExceeded;
+
+    @SerializedName("memorythreshold")
+    @Param(description = "memory usage notification threshold exceeded")
+    private Boolean memoryThresholdExceeded;
+
+    @SerializedName("memorydisablethreshold")
+    @Param(description = "memory usage disable threshold exceeded")
+    private Boolean memoryDisableThresholdExceeded;
+
+    @SerializedName("memoryallocatedthreshold")
+    @Param(description = "memory allocated notification threshold exceeded")
+    private Boolean memoryAllocatedThresholdExceeded;
+
+    @SerializedName("memoryallocateddisablethreshold")
+    @Param(description = "memory allocated disable threshold exceeded")
+    private Boolean memoryAllocatedDisableThresholdExceeded;
+
+
+    public void setState(final String allocationState) {
+        this.state = allocationState;
+    }
+
+    public void setResource(final Long upResources, final Long totalResources) {
+        if (upResources != null && totalResources != null) {
+            this.resources = String.format("%d / %d", upResources, totalResources);
+        }
+    }
+
+    public void setCpuTotal(final Long cpuTotal) {
+        if (cpuTotal != null) {
+            this.cpuTotal = String.format("%.2f Ghz", cpuTotal / 1000.0);
+        }
+    }
+
+    public void setCpuUsed(final Double cpuUsedPercentage, final Long totalHosts) {
+        if (cpuUsedPercentage != null && totalHosts != null && totalHosts != 0) {
+            this.cpuUsed = String.format("%.2f%%", 1.0 * cpuUsedPercentage / totalHosts);
+        }
+    }
+
+    public void setCpuAllocated(final Long cpuAllocated, final Long cpuTotal) {
+        if (cpuAllocated != null && cpuTotal != null && cpuTotal != 0) {
+            this.cpuAllocated = String.format("%.2f%%", cpuAllocated * 100.0 / cpuTotal);
+        }
+    }
+
+    public void setCpuMaxDeviation(final Double maxCpuUsagePercentage, final Double totalCpuUsedPercentage, final Long totalHosts) {
+        if (maxCpuUsagePercentage != null && totalCpuUsedPercentage != null && totalHosts != null && totalHosts != 0) {
+            final Double averageCpuUsagePercentage = totalCpuUsedPercentage / totalHosts;
+            this.cpuMaxDeviation = String.format("%.2f%%", (maxCpuUsagePercentage - averageCpuUsagePercentage) / averageCpuUsagePercentage);
+        }
+    }
+
+    public void setMemTotal(final Long memTotal) {
+        if (memTotal != null) {
+            this.memTotal = String.format("%.2f GB", memTotal / (1024.0 * 1024.0 * 1024.0));
+        }
+    }
+
+    public void setMemUsed( final Long memUsed, final Long memTotal) {
+        if (memUsed != null && memTotal != null) {
+            this.memUsed = String.format("%.2f%%", memUsed * 100.0 / memTotal);
+        }
+    }
+
+    public void setMemAllocated(final Long memAllocated, final Long memTotal) {
+        if (memAllocated != null && memTotal != null && memTotal != 0) {
+            this.memAllocated = String.format("%.2f%%", memAllocated * 100.0 / memTotal);
+        }
+    }
+
+    public void setMemMaxDeviation(final Long maxMemoryUsage, final Long totalMemory, final Long totalHosts) {
+        if (maxMemoryUsage != null && totalMemory != null && totalHosts != null && totalHosts != 0) {
+            final Long averageMemoryUsage = totalMemory / totalHosts;
+            this.memMaxDeviation = String.format("%.2f%%", (maxMemoryUsage - averageMemoryUsage) * 100.0 / averageMemoryUsage);
+        }
+    }
+
+    public void setCpuUsageThreshold(final Double cpuUsed, final Long totalHosts, final Double threshold) {
+        if (cpuUsed != null && totalHosts != null && threshold != null && totalHosts != 0) {
+            this.cpuThresholdExceeded = (cpuUsed / (100.0 * totalHosts)) > threshold;
+        }
+    }
+
+    public void setCpuUsageDisableThreshold(final Double cpuUsed, final Long totalHosts, final Float threshold) {
+        if (cpuUsed != null && totalHosts != null && threshold != null && totalHosts != 0) {
+            this.cpuDisableThresholdExceeded = (cpuUsed / (100.0 * totalHosts)) > threshold;
+        }
+    }
+
+    public void setCpuAllocatedThreshold(final Long cpuAllocated, final Long cpuUsed, final Double threshold) {
+        if (cpuAllocated != null && cpuUsed != null && threshold != null && cpuUsed != 0) {
+            this.cpuAllocatedThresholdExceeded = (1.0 * cpuAllocated / cpuUsed) > threshold;
+        }
+    }
+
+    public void setCpuAllocatedDisableThreshold(final Long cpuAllocated, final Long cpuUsed, final Float threshold) {
+        if (cpuAllocated != null && cpuUsed != null && threshold != null && cpuUsed != 0) {
+            this.cpuAllocatedDisableThresholdExceeded = (1.0 * cpuAllocated / cpuUsed) > threshold;
+        }
+    }
+
+    public void setMemoryUsageThreshold(final Long memUsed, final Long memTotal, final Double threshold) {
+        if (memUsed != null && memTotal != null && threshold != null && memTotal != 0) {
+            this.memoryThresholdExceeded = (1.0 * memUsed / memTotal) > threshold;
+        }
+    }
+
+    public void setMemoryUsageDisableThreshold(final Long memUsed, final Long memTotal, final Float threshold) {
+        if (memUsed != null && memTotal != null && threshold != null && memTotal != 0) {
+            this.memoryDisableThresholdExceeded = (1.0 * memUsed / memTotal) > threshold;
+        }
+    }
+
+
+    public void setMemoryAllocatedThreshold(final Long memAllocated, final Long memTotal, final Double threshold) {
+        if (memAllocated != null && memTotal != null && threshold != null && memTotal != 0) {
+            this.memoryAllocatedThresholdExceeded = (1.0 * memAllocated / memTotal) > threshold;
+        }
+    }
+
+    public void setMemoryAllocatedDisableThreshold(final Long memAllocated, final Long memTotal, final Float threshold) {
+        if (memAllocated != null && memTotal != null && threshold != null && memTotal != 0) {
+            this.memoryAllocatedDisableThresholdExceeded = (1.0 * memAllocated / memTotal) > threshold;
+        }
+    }
+}
diff --git a/plugins/network-elements/bigswitch/pom.xml b/plugins/network-elements/bigswitch/pom.xml
index 8c8c626..6b3057e 100644
--- a/plugins/network-elements/bigswitch/pom.xml
+++ b/plugins/network-elements/bigswitch/pom.xml
@@ -25,7 +25,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack-plugins</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../../pom.xml</relativePath>
   </parent>
   <build>
diff --git a/plugins/network-elements/brocade-vcs/pom.xml b/plugins/network-elements/brocade-vcs/pom.xml
index c0bba78..fdb3858 100644
--- a/plugins/network-elements/brocade-vcs/pom.xml
+++ b/plugins/network-elements/brocade-vcs/pom.xml
@@ -16,7 +16,7 @@
 	<parent>
 		<groupId>org.apache.cloudstack</groupId>
 		<artifactId>cloudstack-plugins</artifactId>
-		<version>4.9.2.0-SNAPSHOT</version>
+		<version>4.9.3.0-SNAPSHOT</version>
 		<relativePath>../../pom.xml</relativePath>
 	</parent>
 
diff --git a/plugins/network-elements/cisco-vnmc/pom.xml b/plugins/network-elements/cisco-vnmc/pom.xml
index 6cbce85..87d4a80 100644
--- a/plugins/network-elements/cisco-vnmc/pom.xml
+++ b/plugins/network-elements/cisco-vnmc/pom.xml
@@ -24,7 +24,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack-plugins</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../../pom.xml</relativePath>
   </parent>
   <dependencies>
diff --git a/plugins/network-elements/dns-notifier/pom.xml b/plugins/network-elements/dns-notifier/pom.xml
index adac280..17fb534 100644
--- a/plugins/network-elements/dns-notifier/pom.xml
+++ b/plugins/network-elements/dns-notifier/pom.xml
@@ -22,7 +22,7 @@
   <parent>

     <groupId>org.apache.cloudstack</groupId>

     <artifactId>cloudstack-plugins</artifactId>

-    <version>4.9.2.0-SNAPSHOT</version>

+    <version>4.9.3.0-SNAPSHOT</version>

     <relativePath>../../pom.xml</relativePath>

   </parent>

   <artifactId>cloud-plugin-example-dns-notifier</artifactId>

diff --git a/plugins/network-elements/elastic-loadbalancer/pom.xml b/plugins/network-elements/elastic-loadbalancer/pom.xml
index 257ab8b..27ae6ae 100644
--- a/plugins/network-elements/elastic-loadbalancer/pom.xml
+++ b/plugins/network-elements/elastic-loadbalancer/pom.xml
@@ -23,7 +23,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack-plugins</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../../pom.xml</relativePath>
   </parent>
 </project>
diff --git a/plugins/network-elements/f5/pom.xml b/plugins/network-elements/f5/pom.xml
index 137c607..7dd2b9b 100644
--- a/plugins/network-elements/f5/pom.xml
+++ b/plugins/network-elements/f5/pom.xml
@@ -23,7 +23,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack-plugins</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../../pom.xml</relativePath>
   </parent>
   <dependencies>
diff --git a/plugins/network-elements/globodns/pom.xml b/plugins/network-elements/globodns/pom.xml
index 324a8cd..f740522 100644
--- a/plugins/network-elements/globodns/pom.xml
+++ b/plugins/network-elements/globodns/pom.xml
@@ -24,7 +24,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack-plugins</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../../pom.xml</relativePath>
   </parent>
   <dependencies>
diff --git a/plugins/network-elements/internal-loadbalancer/pom.xml b/plugins/network-elements/internal-loadbalancer/pom.xml
index f28ea01..c0631be 100644
--- a/plugins/network-elements/internal-loadbalancer/pom.xml
+++ b/plugins/network-elements/internal-loadbalancer/pom.xml
@@ -23,7 +23,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack-plugins</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../../pom.xml</relativePath>
   </parent>
   <build>
diff --git a/plugins/network-elements/juniper-contrail/pom.xml b/plugins/network-elements/juniper-contrail/pom.xml
index 7fcba22..94ee3d1 100644
--- a/plugins/network-elements/juniper-contrail/pom.xml
+++ b/plugins/network-elements/juniper-contrail/pom.xml
@@ -23,7 +23,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack-plugins</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../../pom.xml</relativePath>
   </parent>
   <repositories>
diff --git a/plugins/network-elements/juniper-srx/pom.xml b/plugins/network-elements/juniper-srx/pom.xml
index 5ef0526..bbacf84 100644
--- a/plugins/network-elements/juniper-srx/pom.xml
+++ b/plugins/network-elements/juniper-srx/pom.xml
@@ -23,7 +23,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack-plugins</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../../pom.xml</relativePath>
   </parent>
   <dependencies>
diff --git a/plugins/network-elements/midonet/pom.xml b/plugins/network-elements/midonet/pom.xml
index dc4719c..0f23ef3 100644
--- a/plugins/network-elements/midonet/pom.xml
+++ b/plugins/network-elements/midonet/pom.xml
@@ -23,7 +23,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack-plugins</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../../pom.xml</relativePath>
   </parent>
 <repositories>
diff --git a/plugins/network-elements/netscaler/pom.xml b/plugins/network-elements/netscaler/pom.xml
index c884c94..b84fdf7 100644
--- a/plugins/network-elements/netscaler/pom.xml
+++ b/plugins/network-elements/netscaler/pom.xml
@@ -23,7 +23,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack-plugins</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../../pom.xml</relativePath>
   </parent>
   <dependencies>
diff --git a/plugins/network-elements/nicira-nvp/pom.xml b/plugins/network-elements/nicira-nvp/pom.xml
index 58b6553..7563560 100644
--- a/plugins/network-elements/nicira-nvp/pom.xml
+++ b/plugins/network-elements/nicira-nvp/pom.xml
@@ -26,7 +26,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack-plugins</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../../pom.xml</relativePath>
   </parent>
 
@@ -34,7 +34,7 @@
     <dependency>
       <groupId>org.apache.cloudstack</groupId>
       <artifactId>cloud-utils</artifactId>
-      <version>4.9.2.0-SNAPSHOT</version>
+      <version>4.9.3.0-SNAPSHOT</version>
       <type>test-jar</type>
       <scope>test</scope>
     </dependency>
diff --git a/plugins/network-elements/nuage-vsp/pom.xml b/plugins/network-elements/nuage-vsp/pom.xml
index 92d7eb6..a792c14 100644
--- a/plugins/network-elements/nuage-vsp/pom.xml
+++ b/plugins/network-elements/nuage-vsp/pom.xml
@@ -25,7 +25,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack-plugins</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../../pom.xml</relativePath>
   </parent>
   <repositories>
diff --git a/plugins/network-elements/opendaylight/pom.xml b/plugins/network-elements/opendaylight/pom.xml
index 3e03227..9800887 100644
--- a/plugins/network-elements/opendaylight/pom.xml
+++ b/plugins/network-elements/opendaylight/pom.xml
@@ -25,7 +25,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack-plugins</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../../pom.xml</relativePath>
   </parent>
 
diff --git a/plugins/network-elements/ovs/pom.xml b/plugins/network-elements/ovs/pom.xml
index 7b8eb19..7f79024 100644
--- a/plugins/network-elements/ovs/pom.xml
+++ b/plugins/network-elements/ovs/pom.xml
@@ -23,7 +23,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack-plugins</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../../pom.xml</relativePath>
   </parent>
 </project>
diff --git a/plugins/network-elements/palo-alto/pom.xml b/plugins/network-elements/palo-alto/pom.xml
index 9d7108d..1c9d081 100644
--- a/plugins/network-elements/palo-alto/pom.xml
+++ b/plugins/network-elements/palo-alto/pom.xml
@@ -23,7 +23,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack-plugins</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../../pom.xml</relativePath>
   </parent>
 </project>
diff --git a/plugins/network-elements/stratosphere-ssp/pom.xml b/plugins/network-elements/stratosphere-ssp/pom.xml
index b949d42..0b0196e 100644
--- a/plugins/network-elements/stratosphere-ssp/pom.xml
+++ b/plugins/network-elements/stratosphere-ssp/pom.xml
@@ -25,7 +25,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack-plugins</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../../pom.xml</relativePath>
   </parent>
 </project>
diff --git a/plugins/network-elements/vxlan/pom.xml b/plugins/network-elements/vxlan/pom.xml
index 2203b93..d40e691 100644
--- a/plugins/network-elements/vxlan/pom.xml
+++ b/plugins/network-elements/vxlan/pom.xml
@@ -23,7 +23,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack-plugins</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../../pom.xml</relativePath>
   </parent>
 </project>
diff --git a/plugins/outofbandmanagement-drivers/ipmitool/pom.xml b/plugins/outofbandmanagement-drivers/ipmitool/pom.xml
index 3971dbc..c97899b 100644
--- a/plugins/outofbandmanagement-drivers/ipmitool/pom.xml
+++ b/plugins/outofbandmanagement-drivers/ipmitool/pom.xml
@@ -23,7 +23,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack-plugins</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../../pom.xml</relativePath>
   </parent>
   <dependencies>
diff --git a/plugins/pom.xml b/plugins/pom.xml
index d0119f0..72a7bc1 100755
--- a/plugins/pom.xml
+++ b/plugins/pom.xml
@@ -26,7 +26,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
   </parent>
 
   <build>
@@ -69,6 +69,7 @@
     <module>hypervisors/ucs</module>
     <module>hypervisors/hyperv</module>
     <module>hypervisors/ovm3</module>
+    <module>metrics</module>
     <module>network-elements/elastic-loadbalancer</module>
     <module>network-elements/ovs</module>
     <module>network-elements/juniper-contrail</module>
diff --git a/plugins/storage-allocators/random/pom.xml b/plugins/storage-allocators/random/pom.xml
index 1a6665a..85f271e 100644
--- a/plugins/storage-allocators/random/pom.xml
+++ b/plugins/storage-allocators/random/pom.xml
@@ -24,7 +24,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack-plugins</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../../pom.xml</relativePath>
   </parent>
   <dependencies>
diff --git a/plugins/storage/image/default/pom.xml b/plugins/storage/image/default/pom.xml
index 7b68b5a..429e9d5 100644
--- a/plugins/storage/image/default/pom.xml
+++ b/plugins/storage/image/default/pom.xml
@@ -16,7 +16,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack-plugins</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../../../pom.xml</relativePath>
   </parent>
   <dependencies>
diff --git a/plugins/storage/image/s3/pom.xml b/plugins/storage/image/s3/pom.xml
index d212e92..2b40167 100644
--- a/plugins/storage/image/s3/pom.xml
+++ b/plugins/storage/image/s3/pom.xml
@@ -23,7 +23,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack-plugins</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../../../pom.xml</relativePath>
   </parent>
   <dependencies>
diff --git a/plugins/storage/image/sample/pom.xml b/plugins/storage/image/sample/pom.xml
index 0c2011e..04c2e32 100644
--- a/plugins/storage/image/sample/pom.xml
+++ b/plugins/storage/image/sample/pom.xml
@@ -16,7 +16,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack-plugins</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../../../pom.xml</relativePath>
   </parent>
   <dependencies>
diff --git a/plugins/storage/image/swift/pom.xml b/plugins/storage/image/swift/pom.xml
index c9bd8bf..09586f3 100644
--- a/plugins/storage/image/swift/pom.xml
+++ b/plugins/storage/image/swift/pom.xml
@@ -16,7 +16,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack-plugins</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../../../pom.xml</relativePath>
   </parent>
   <dependencies>
diff --git a/plugins/storage/volume/cloudbyte/pom.xml b/plugins/storage/volume/cloudbyte/pom.xml
index 2472d62..ae24d99 100755
--- a/plugins/storage/volume/cloudbyte/pom.xml
+++ b/plugins/storage/volume/cloudbyte/pom.xml
@@ -26,7 +26,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack-plugins</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../../../pom.xml</relativePath>
   </parent>
   <dependencies>
diff --git a/plugins/storage/volume/default/pom.xml b/plugins/storage/volume/default/pom.xml
index 3b44a5a..6f1bbce 100644
--- a/plugins/storage/volume/default/pom.xml
+++ b/plugins/storage/volume/default/pom.xml
@@ -16,7 +16,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack-plugins</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../../../pom.xml</relativePath>
   </parent>
   <dependencies>
diff --git a/plugins/storage/volume/nexenta/pom.xml b/plugins/storage/volume/nexenta/pom.xml
index 95e39a4..a994237 100644
--- a/plugins/storage/volume/nexenta/pom.xml
+++ b/plugins/storage/volume/nexenta/pom.xml
@@ -16,7 +16,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack-plugins</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../../../pom.xml</relativePath>
   </parent>
   <dependencies>
diff --git a/plugins/storage/volume/sample/pom.xml b/plugins/storage/volume/sample/pom.xml
index f214c2e..4a0aa98 100644
--- a/plugins/storage/volume/sample/pom.xml
+++ b/plugins/storage/volume/sample/pom.xml
@@ -16,7 +16,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack-plugins</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../../../pom.xml</relativePath>
   </parent>
   <dependencies>
diff --git a/plugins/storage/volume/solidfire/pom.xml b/plugins/storage/volume/solidfire/pom.xml
index bbbc4df..56db8c8 100644
--- a/plugins/storage/volume/solidfire/pom.xml
+++ b/plugins/storage/volume/solidfire/pom.xml
@@ -16,7 +16,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack-plugins</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../../../pom.xml</relativePath>
   </parent>
   <dependencies>
diff --git a/plugins/user-authenticators/ldap/pom.xml b/plugins/user-authenticators/ldap/pom.xml
index 58ca180d..9e89978 100644
--- a/plugins/user-authenticators/ldap/pom.xml
+++ b/plugins/user-authenticators/ldap/pom.xml
@@ -15,7 +15,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack-plugins</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../../pom.xml</relativePath>
   </parent>
 
diff --git a/plugins/user-authenticators/md5/pom.xml b/plugins/user-authenticators/md5/pom.xml
index a56dca5..39c745b 100644
--- a/plugins/user-authenticators/md5/pom.xml
+++ b/plugins/user-authenticators/md5/pom.xml
@@ -23,7 +23,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack-plugins</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../../pom.xml</relativePath>
   </parent>
 </project>
diff --git a/plugins/user-authenticators/pbkdf2/pom.xml b/plugins/user-authenticators/pbkdf2/pom.xml
index d3dceba..9abdcd4 100644
--- a/plugins/user-authenticators/pbkdf2/pom.xml
+++ b/plugins/user-authenticators/pbkdf2/pom.xml
@@ -23,7 +23,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack-plugins</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../../pom.xml</relativePath>
   </parent>
 </project>
diff --git a/plugins/user-authenticators/plain-text/pom.xml b/plugins/user-authenticators/plain-text/pom.xml
index 96a225f..3664487 100644
--- a/plugins/user-authenticators/plain-text/pom.xml
+++ b/plugins/user-authenticators/plain-text/pom.xml
@@ -23,7 +23,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack-plugins</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../../pom.xml</relativePath>
   </parent>
 </project>
diff --git a/plugins/user-authenticators/saml2/pom.xml b/plugins/user-authenticators/saml2/pom.xml
index 2f611be..e35391f 100644
--- a/plugins/user-authenticators/saml2/pom.xml
+++ b/plugins/user-authenticators/saml2/pom.xml
@@ -23,7 +23,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack-plugins</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../../pom.xml</relativePath>
   </parent>
   <dependencies>
diff --git a/plugins/user-authenticators/sha256salted/pom.xml b/plugins/user-authenticators/sha256salted/pom.xml
index 2121bf4..76daf84 100644
--- a/plugins/user-authenticators/sha256salted/pom.xml
+++ b/plugins/user-authenticators/sha256salted/pom.xml
@@ -23,7 +23,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack-plugins</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../../pom.xml</relativePath>
   </parent>
 </project>
diff --git a/pom.xml b/pom.xml
index f521e77..f546f6f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -30,7 +30,7 @@
 
   <groupId>org.apache.cloudstack</groupId>
   <artifactId>cloudstack</artifactId>
-  <version>4.9.2.0-SNAPSHOT</version>
+  <version>4.9.3.0-SNAPSHOT</version>
   <packaging>pom</packaging>
   <name>Apache CloudStack</name>
   <description>Apache CloudStack is an IaaS (“Infrastructure as a Service”) cloud orchestration platform.</description>
diff --git a/quickcloud/pom.xml b/quickcloud/pom.xml
index 80f4ff7..63de3de 100644
--- a/quickcloud/pom.xml
+++ b/quickcloud/pom.xml
@@ -24,7 +24,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloud-maven-standard</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../maven-standard/pom.xml</relativePath>
   </parent>
 </project>
diff --git a/server/pom.xml b/server/pom.xml
index 2aa2f12..02d568f 100644
--- a/server/pom.xml
+++ b/server/pom.xml
@@ -15,7 +15,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
   </parent>
   <dependencies>
     <dependency>
diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java
index 6a7f0ab..eaf48c7 100644
--- a/server/src/com/cloud/api/ApiResponseHelper.java
+++ b/server/src/com/cloud/api/ApiResponseHelper.java
@@ -527,6 +527,9 @@
 
         long storagePoolId = snapshotStore.getDataStoreId();
         DataStore dataStore = dataStoreMgr.getDataStore(storagePoolId, DataStoreRole.Primary);
+        if (dataStore == null) {
+            return DataStoreRole.Image;
+        }
 
         Map<String, String> mapCapabilities = dataStore.getDriver().getCapabilities();
 
diff --git a/server/src/com/cloud/api/auth/DefaultLoginAPIAuthenticatorCmd.java b/server/src/com/cloud/api/auth/DefaultLoginAPIAuthenticatorCmd.java
index c83e708..249be78 100644
--- a/server/src/com/cloud/api/auth/DefaultLoginAPIAuthenticatorCmd.java
+++ b/server/src/com/cloud/api/auth/DefaultLoginAPIAuthenticatorCmd.java
@@ -166,7 +166,7 @@
                     throw new CloudAuthenticationException("Unable to find the domain from the path " + domain);
                 }
                 final UserAccount userAccount = _accountService.getActiveUserAccount(username[0], domainId);
-                if (userAccount == null || !(User.Source.UNKNOWN.equals(userAccount.getSource()) || User.Source.LDAP.equals(userAccount.getSource()))) {
+                if (userAccount != null && User.Source.SAML2 == userAccount.getSource()) {
                     throw new CloudAuthenticationException("User is not allowed CloudStack login");
                 }
                 return ApiResponseSerializer.toSerializedString(_apiServer.loginUser(session, username[0], pwd, domainId, domain, remoteAddress, params),
diff --git a/server/src/com/cloud/api/query/dao/HostJoinDao.java b/server/src/com/cloud/api/query/dao/HostJoinDao.java
index f0ac183..e7dc5d5 100644
--- a/server/src/com/cloud/api/query/dao/HostJoinDao.java
+++ b/server/src/com/cloud/api/query/dao/HostJoinDao.java
@@ -41,4 +41,6 @@
 
     List<HostJoinVO> searchByIds(Long... ids);
 
+    List<HostJoinVO> findByClusterId(Long clusterId, Host.Type type);
+
 }
diff --git a/server/src/com/cloud/api/query/dao/HostJoinDaoImpl.java b/server/src/com/cloud/api/query/dao/HostJoinDaoImpl.java
index 6c15a8b..58a0366 100644
--- a/server/src/com/cloud/api/query/dao/HostJoinDaoImpl.java
+++ b/server/src/com/cloud/api/query/dao/HostJoinDaoImpl.java
@@ -65,6 +65,8 @@
 
     private final SearchBuilder<HostJoinVO> hostIdSearch;
 
+    private final SearchBuilder<HostJoinVO> ClusterSearch;
+
     protected HostJoinDaoImpl() {
 
         hostSearch = createSearchBuilder();
@@ -75,6 +77,11 @@
         hostIdSearch.and("id", hostIdSearch.entity().getId(), SearchCriteria.Op.EQ);
         hostIdSearch.done();
 
+        ClusterSearch = createSearchBuilder();
+        ClusterSearch.and("clusterId", ClusterSearch.entity().getClusterId(), SearchCriteria.Op.EQ);
+        ClusterSearch.and("type", ClusterSearch.entity().getType(), SearchCriteria.Op.EQ);
+        ClusterSearch.done();
+
         this._count = "select count(distinct id) from host_view WHERE ";
     }
 
@@ -432,4 +439,12 @@
         return uvList;
     }
 
+    @Override
+    public List<HostJoinVO> findByClusterId(Long clusterId, Host.Type type) {
+        SearchCriteria<HostJoinVO> sc = ClusterSearch.create();
+        sc.setParameters("clusterId", clusterId);
+        sc.setParameters("type", type);
+        return listBy(sc);
+    }
+
 }
diff --git a/server/src/com/cloud/configuration/Config.java b/server/src/com/cloud/configuration/Config.java
index 600ecc4..d502536 100644
--- a/server/src/com/cloud/configuration/Config.java
+++ b/server/src/com/cloud/configuration/Config.java
@@ -512,7 +512,7 @@
             null),
     SnapshotDeltaMax("Snapshots", SnapshotManager.class, Integer.class, "snapshot.delta.max", "16", "max delta snapshots between two full snapshots.", null),
     BackupSnapshotAfterTakingSnapshot(
-            "Hidden",
+            "Snapshots",
             SnapshotManager.class,
             Boolean.class,
             "snapshot.backup.rightafter",
diff --git a/server/src/com/cloud/deploy/DeploymentPlanningManagerImpl.java b/server/src/com/cloud/deploy/DeploymentPlanningManagerImpl.java
index ef0ad19..80c417e 100644
--- a/server/src/com/cloud/deploy/DeploymentPlanningManagerImpl.java
+++ b/server/src/com/cloud/deploy/DeploymentPlanningManagerImpl.java
@@ -588,7 +588,7 @@
         List<Long> allDedicatedPods = _dedicatedDao.listAllPods();
         allPodsInDc.retainAll(allDedicatedPods);
 
-        List<Long> allClustersInDc = _clusterDao.listAllCusters(dc.getId());
+        List<Long> allClustersInDc = _clusterDao.listAllClusters(dc.getId());
         List<Long> allDedicatedClusters = _dedicatedDao.listAllClusters();
         allClustersInDc.retainAll(allDedicatedClusters);
 
diff --git a/server/src/com/cloud/network/NetworkServiceImpl.java b/server/src/com/cloud/network/NetworkServiceImpl.java
index b6dac87..e77b40e 100644
--- a/server/src/com/cloud/network/NetworkServiceImpl.java
+++ b/server/src/com/cloud/network/NetworkServiceImpl.java
@@ -835,7 +835,7 @@
                 }
             }
             //check if the secondary ip associated with any static nat rule
-            IPAddressVO publicIpVO = _ipAddressDao.findByVmIp(secondaryIp);
+            IPAddressVO publicIpVO = _ipAddressDao.findByIpAndNetworkId(secIpVO.getNetworkId(), secondaryIp);
             if (publicIpVO != null) {
                 s_logger.debug("VM nic IP " + secondaryIp + " is associated with the static NAT rule public IP address id " + publicIpVO.getId());
                 throw new InvalidParameterValueException("Can' remove the ip " + secondaryIp + "is associate with static NAT rule public IP address id " + publicIpVO.getId());
diff --git a/server/src/com/cloud/network/router/CommandSetupHelper.java b/server/src/com/cloud/network/router/CommandSetupHelper.java
index 7208b25..3e4318a 100644
--- a/server/src/com/cloud/network/router/CommandSetupHelper.java
+++ b/server/src/com/cloud/network/router/CommandSetupHelper.java
@@ -108,8 +108,6 @@
 import com.cloud.offerings.NetworkOfferingVO;
 import com.cloud.offerings.dao.NetworkOfferingDao;
 import com.cloud.service.dao.ServiceOfferingDao;
-import com.cloud.storage.GuestOSVO;
-import com.cloud.storage.dao.GuestOSDao;
 import com.cloud.user.Account;
 import com.cloud.uservm.UserVm;
 import com.cloud.utils.Pair;
@@ -174,8 +172,6 @@
     private VlanDao _vlanDao;
     @Inject
     private IPAddressDao _ipAddressDao;
-    @Inject
-    private GuestOSDao _guestOSDao;
 
     @Inject
     private RouterControlHelper _routerControlHelper;
@@ -184,8 +180,6 @@
     @Qualifier("networkHelper")
     protected NetworkHelper _networkHelper;
 
-    private final String _dnsBasicZoneUpdates = "all";
-
     public void createVmDataCommand(final VirtualRouter router, final UserVm vm, final NicVO nic, final String publicKey, final Commands cmds) {
         final String serviceOffering = _serviceOfferingDao.findByIdIncludingRemoved(vm.getId(), vm.getServiceOfferingId()).getDisplayText();
         final String zoneName = _dcDao.findById(router.getDataCenterId()).getName();
@@ -221,12 +215,6 @@
                 _networkModel.getExecuteInSeqNtwkElmtCmd());
 
         String gatewayIp = nic.getIPv4Gateway();
-        if (!nic.isDefaultNic()) {
-            final GuestOSVO guestOS = _guestOSDao.findById(vm.getGuestOSId());
-            if (guestOS == null || !guestOS.getDisplayName().toLowerCase().contains("windows")) {
-                gatewayIp = "0.0.0.0";
-            }
-        }
 
         final DataCenterVO dcVo = _dcDao.findById(router.getDataCenterId());
 
@@ -620,18 +608,17 @@
     public void createDhcpEntryCommandsForVMs(final DomainRouterVO router, final Commands cmds, final long guestNetworkId) {
         final List<UserVmVO> vms = _userVmDao.listByNetworkIdAndStates(guestNetworkId, VirtualMachine.State.Running, VirtualMachine.State.Migrating, VirtualMachine.State.Stopping);
         final DataCenterVO dc = _dcDao.findById(router.getDataCenterId());
+        String dnsBasicZoneUpdates = _configDao.getValue(Config.DnsBasicZoneUpdates.key());
         for (final UserVmVO vm : vms) {
-            boolean createDhcp = true;
             if (dc.getNetworkType() == NetworkType.Basic && router.getPodIdToDeployIn().longValue() != vm.getPodIdToDeployIn().longValue()
-                    && _dnsBasicZoneUpdates.equalsIgnoreCase("pod")) {
-                createDhcp = false;
+                    && dnsBasicZoneUpdates.equalsIgnoreCase("pod")) {
+                continue;
             }
-            if (createDhcp) {
-                final NicVO nic = _nicDao.findByNtwkIdAndInstanceId(guestNetworkId, vm.getId());
-                if (nic != null) {
-                    s_logger.debug("Creating dhcp entry for vm " + vm + " on domR " + router + ".");
-                    createDhcpEntryCommand(router, vm, nic, cmds);
-                }
+
+            final NicVO nic = _nicDao.findByNtwkIdAndInstanceId(guestNetworkId, vm.getId());
+            if (nic != null) {
+                s_logger.debug("Creating dhcp entry for vm " + vm + " on domR " + router + ".");
+                createDhcpEntryCommand(router, vm, nic, cmds);
             }
         }
     }
diff --git a/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java
index c2d923c..228a4de 100644
--- a/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java
+++ b/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java
@@ -88,6 +88,10 @@
 import com.cloud.vm.VirtualMachineProfile;
 import com.cloud.vm.VirtualMachineProfile.Param;
 import com.cloud.vm.dao.VMInstanceDao;
+import com.cloud.agent.api.to.VirtualMachineTO;
+import com.cloud.hypervisor.Hypervisor;
+import com.cloud.hypervisor.HypervisorGuru;
+import com.cloud.hypervisor.HypervisorGuruManager;
 
 import org.apache.log4j.Logger;
 import org.springframework.stereotype.Component;
@@ -114,6 +118,8 @@
     private NetworkACLItemDao _networkACLItemDao;
     @Inject
     private EntityManager _entityMgr;
+    @Inject
+    protected HypervisorGuruManager _hvGuruMgr;
 
     @Override
     public boolean configure(final String name, final Map<String, Object> params) throws ConfigurationException {
@@ -280,6 +286,16 @@
     public boolean finalizeCommandsOnStart(final Commands cmds, final VirtualMachineProfile profile) {
         final DomainRouterVO domainRouterVO = _routerDao.findById(profile.getId());
 
+        Map<String, String> details = new HashMap<String, String>();
+
+        if(profile.getHypervisorType() == Hypervisor.HypervisorType.VMware){
+            HypervisorGuru hvGuru = _hvGuruMgr.getGuru(profile.getHypervisorType());
+            VirtualMachineTO vmTO = hvGuru.implement(profile);
+            if(vmTO.getDetails() != null){
+                details = vmTO.getDetails();
+            }
+        }
+
         final boolean isVpc = domainRouterVO.getVpcId() != null;
         if (!isVpc) {
             return super.finalizeCommandsOnStart(cmds, profile);
@@ -338,7 +354,7 @@
                         }
                     }
                     final PlugNicCommand plugNicCmd = new PlugNicCommand(_nwHelper.getNicTO(domainRouterVO, publicNic.getNetworkId(), publicNic.getBroadcastUri().toString()),
-                            domainRouterVO.getInstanceName(), domainRouterVO.getType());
+                            domainRouterVO.getInstanceName(), domainRouterVO.getType(), details);
                     cmds.addCommand(plugNicCmd);
                     final VpcVO vpc = _vpcDao.findById(domainRouterVO.getVpcId());
                     final NetworkUsageCommand netUsageCmd = new NetworkUsageCommand(domainRouterVO.getPrivateIpAddress(), domainRouterVO.getInstanceName(), true, publicNic.getIPv4Address(), vpc.getCidr());
@@ -361,7 +377,7 @@
                 for (final Pair<Nic, Network> nicNtwk : guestNics) {
                     final Nic guestNic = nicNtwk.first();
                     // plug guest nic
-                    final PlugNicCommand plugNicCmd = new PlugNicCommand(_nwHelper.getNicTO(domainRouterVO, guestNic.getNetworkId(), null), domainRouterVO.getInstanceName(), domainRouterVO.getType());
+                    final PlugNicCommand plugNicCmd = new PlugNicCommand(_nwHelper.getNicTO(domainRouterVO, guestNic.getNetworkId(), null), domainRouterVO.getInstanceName(), domainRouterVO.getType(), details);
                     cmds.addCommand(plugNicCmd);
                     if (!_networkModel.isPrivateGateway(guestNic.getNetworkId())) {
                         // set guest network
diff --git a/server/src/com/cloud/network/vpn/RemoteAccessVpnManagerImpl.java b/server/src/com/cloud/network/vpn/RemoteAccessVpnManagerImpl.java
index b473f05..2a84714 100644
--- a/server/src/com/cloud/network/vpn/RemoteAccessVpnManagerImpl.java
+++ b/server/src/com/cloud/network/vpn/RemoteAccessVpnManagerImpl.java
@@ -521,21 +521,26 @@
 
         boolean success = true;
 
-        boolean[] finals = new boolean[users.size()];
+        Boolean[] finals = new Boolean[users.size()];
         for (RemoteAccessVPNServiceProvider element : _vpnServiceProviders) {
             s_logger.debug("Applying vpn access to " + element.getName());
             for (RemoteAccessVpnVO vpn : vpns) {
                 try {
                     String[] results = element.applyVpnUsers(vpn, users);
                     if (results != null) {
+                        int indexUser = -1;
                         for (int i = 0; i < results.length; i++) {
-                            s_logger.debug("VPN User " + users.get(i) + (results[i] == null ? " is set on " : (" couldn't be set due to " + results[i]) + " on ") + vpn);
+                            indexUser ++;
+                            if (indexUser == users.size()) {
+                                indexUser = 0; // results on multiple VPC routers are combined in commit 13eb789, reset user index if one VR is done.
+                            }
+                            s_logger.debug("VPN User " + users.get(indexUser) + (results[i] == null ? " is set on " : (" couldn't be set due to " + results[i]) + " on ") + vpn.getUuid());
                             if (results[i] == null) {
-                                if (!finals[i]) {
-                                    finals[i] = true;
+                                if (finals[indexUser] == null) {
+                                    finals[indexUser] = true;
                                 }
                             } else {
-                                finals[i] = false;
+                                finals[indexUser] = false;
                                 success = false;
                             }
                         }
diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java
index c0dda25..a5ffbb0 100644
--- a/server/src/com/cloud/storage/StorageManagerImpl.java
+++ b/server/src/com/cloud/storage/StorageManagerImpl.java
@@ -1719,6 +1719,9 @@
         }
 
         // allocated space includes templates
+        if(s_logger.isDebugEnabled()) {
+            s_logger.debug("Destination pool id: " + pool.getId());
+        }
         StoragePoolVO poolVO = _storagePoolDao.findById(pool.getId());
         long allocatedSizeWithTemplate = _capacityMgr.getAllocatedPoolCapacity(poolVO, null);
         long totalAskingSize = 0;
@@ -1746,10 +1749,12 @@
                     allocatedSizeWithTemplate = _capacityMgr.getAllocatedPoolCapacity(poolVO, tmpl);
                 }
             }
-
-            if (volumeVO.getState() != Volume.State.Ready) {
-                totalAskingSize += getDataObjectSizeIncludingHypervisorSnapshotReserve(volumeVO, pool);
-
+            // A ready state volume is already allocated in a pool. so the asking size is zero for it.
+            // In case the volume is moving across pools or is not ready yet, the asking size has to be computed
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("pool id for the volume with id: " + volumeVO.getId() + " is " + volumeVO.getPoolId());
+            }
+            if ((volumeVO.getState() != Volume.State.Ready) || (volumeVO.getPoolId() != pool.getId())) {
                 if (ScopeType.ZONE.equals(poolVO.getScope()) && volumeVO.getTemplateId() != null) {
                     VMTemplateVO tmpl = _templateDao.findByIdIncludingRemoved(volumeVO.getTemplateId());
 
diff --git a/server/src/com/cloud/storage/VolumeApiServiceImpl.java b/server/src/com/cloud/storage/VolumeApiServiceImpl.java
index 77ecc2a..2a9f02d 100644
--- a/server/src/com/cloud/storage/VolumeApiServiceImpl.java
+++ b/server/src/com/cloud/storage/VolumeApiServiceImpl.java
@@ -2146,13 +2146,6 @@
             throw new InvalidParameterValueException("Can't find zone by id " + volume.getDataCenterId());
         }
 
-        if (volume.getInstanceId() != null) {
-            // Check that Vm to which this volume is attached does not have VM Snapshots
-            if (_vmSnapshotDao.findByVm(volume.getInstanceId()).size() > 0) {
-                throw new InvalidParameterValueException("Volume snapshot is not allowed, please detach it from VM with VM Snapshots");
-            }
-        }
-
         if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(caller.getId())) {
             throw new PermissionDeniedException("Cannot perform this operation, Zone is currently disabled: " + zone.getName());
         }
diff --git a/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java b/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java
index 9a363be..9c3cd46 100644
--- a/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java
+++ b/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java
@@ -1019,7 +1019,13 @@
                 DataStoreRole dataStoreRole = getDataStoreRole(snapshot, _snapshotStoreDao, dataStoreMgr);
 
                 SnapshotDataStoreVO snapshotStoreRef = _snapshotStoreDao.findBySnapshot(snapshotId, dataStoreRole);
-
+                if(snapshotStoreRef == null) {
+                    // The snapshot was not backed up to secondary.  Find the snap on primary
+                    snapshotStoreRef = _snapshotStoreDao.findBySnapshot(snapshotId, DataStoreRole.Primary);
+                    if(snapshotStoreRef == null) {
+                        throw new CloudRuntimeException("Could not find snapshot");
+                    }
+                }
                 UsageEventUtils.publishUsageEvent(EventTypes.EVENT_SNAPSHOT_CREATE, snapshot.getAccountId(), snapshot.getDataCenterId(), snapshotId, snapshot.getName(),
                     null, null, snapshotStoreRef.getPhysicalSize(), volume.getSize(), snapshot.getClass().getName(), snapshot.getUuid());
 
diff --git a/server/src/com/cloud/template/TemplateManagerImpl.java b/server/src/com/cloud/template/TemplateManagerImpl.java
index 7130042..94d2fc9 100644
--- a/server/src/com/cloud/template/TemplateManagerImpl.java
+++ b/server/src/com/cloud/template/TemplateManagerImpl.java
@@ -75,7 +75,10 @@
 import org.apache.cloudstack.engine.subsystem.api.storage.Scope;
 import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory;
 import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo;
+import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotStrategy;
+import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotStrategy.SnapshotOperation;
 import org.apache.cloudstack.engine.subsystem.api.storage.StorageCacheManager;
+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;
@@ -254,6 +257,8 @@
     @Inject
     private SnapshotDataFactory _snapshotFactory;
     @Inject
+    StorageStrategyFactory _storageStrategyFactory;
+    @Inject
     private TemplateService _tmpltSvr;
     @Inject
     private DataStoreManager _dataStoreMgr;
@@ -1493,6 +1498,21 @@
                 SnapshotInfo snapInfo = _snapshotFactory.getSnapshot(snapshotId, dataStoreRole);
 
                 if (dataStoreRole == DataStoreRole.Image) {
+                    if (snapInfo == null) {
+                        snapInfo = _snapshotFactory.getSnapshot(snapshotId, DataStoreRole.Primary);
+                        if(snapInfo == null) {
+                            throw new CloudRuntimeException("Cannot find snapshot "+snapshotId);
+                        }
+                        // We need to copy the snapshot onto secondary.
+                        SnapshotStrategy snapshotStrategy = _storageStrategyFactory.getSnapshotStrategy(snapshot, SnapshotOperation.BACKUP);
+                        snapshotStrategy.backupSnapshot(snapInfo);
+
+                        // Attempt to grab it again.
+                        snapInfo = _snapshotFactory.getSnapshot(snapshotId, dataStoreRole);
+                        if(snapInfo == null) {
+                            throw new CloudRuntimeException("Cannot find snapshot " + snapshotId + " on secondary and could not create backup");
+                        }
+                    }
                     DataStore snapStore = snapInfo.getDataStore();
 
                     if (snapStore != null) {
diff --git a/server/src/com/cloud/user/DomainManagerImpl.java b/server/src/com/cloud/user/DomainManagerImpl.java
index 13dcd90..6973ea1 100644
--- a/server/src/com/cloud/user/DomainManagerImpl.java
+++ b/server/src/com/cloud/user/DomainManagerImpl.java
@@ -373,7 +373,7 @@
             List<DomainVO> domains = _domainDao.search(sc, null);
 
             SearchCriteria<DomainVO> sc1 = _domainDao.createSearchCriteria();
-            sc1.addAnd("path", SearchCriteria.Op.LIKE, "%" + domainHandle.getPath() + "%");
+            sc1.addAnd("path", SearchCriteria.Op.LIKE, "%" + "replace(" + domainHandle.getPath() + ", '%', '[%]')" + "%");
             List<DomainVO> domainsToBeInactivated = _domainDao.search(sc1, null);
 
             // update all subdomains to inactive so no accounts/users can be created
diff --git a/server/src/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java b/server/src/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java
index bb1536d..5e6ec1c 100644
--- a/server/src/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java
+++ b/server/src/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java
@@ -263,11 +263,6 @@
             throw new InvalidParameterValueException("Creating VM snapshot failed due to VM:" + vmId + " is a system VM or does not exist");
         }
 
-        if (_snapshotDao.listByInstanceId(vmId, Snapshot.State.BackedUp).size() > 0) {
-            throw new InvalidParameterValueException(
-                    "VM snapshot for this VM is not allowed. This VM has volumes attached which has snapshots, please remove all snapshots before taking VM snapshot");
-        }
-
         // VM snapshot with memory is not supported for VGPU Vms
         if (snapshotMemory && _serviceOfferingDetailsDao.findDetail(userVmVo.getServiceOfferingId(), GPU.Keys.vgpuType.toString()) != null) {
             throw new InvalidParameterValueException("VM snapshot with MEMORY is not supported for vGPU enabled VMs.");
diff --git a/server/test/com/cloud/template/TemplateManagerImplTest.java b/server/test/com/cloud/template/TemplateManagerImplTest.java
index 6e16938..e6e9edd 100644
--- a/server/test/com/cloud/template/TemplateManagerImplTest.java
+++ b/server/test/com/cloud/template/TemplateManagerImplTest.java
@@ -68,6 +68,7 @@
 import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStore;
 import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory;
 import org.apache.cloudstack.engine.subsystem.api.storage.StorageCacheManager;
+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.TemplateService;
 import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
@@ -161,6 +162,9 @@
     @Inject
     SnapshotDao snapshotDao;
 
+    @Inject
+    StorageStrategyFactory storageStrategyFactory;
+
     public class CustomThreadPoolExecutor extends ThreadPoolExecutor {
         AtomicInteger ai = new AtomicInteger(0);
         public CustomThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit,
@@ -454,6 +458,11 @@
         }
 
         @Bean
+        public StorageStrategyFactory storageStrategyFactory() {
+            return Mockito.mock(StorageStrategyFactory.class);
+        }
+
+        @Bean
         public VMTemplatePoolDao vmTemplatePoolDao() {
             return Mockito.mock(VMTemplatePoolDao.class);
         }
diff --git a/services/console-proxy-rdp/rdpconsole/pom.xml b/services/console-proxy-rdp/rdpconsole/pom.xml
index c6d2f75..a3ab466 100755
--- a/services/console-proxy-rdp/rdpconsole/pom.xml
+++ b/services/console-proxy-rdp/rdpconsole/pom.xml
@@ -27,7 +27,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack-services</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../../pom.xml</relativePath>
   </parent>
 
diff --git a/services/console-proxy/plugin/pom.xml b/services/console-proxy/plugin/pom.xml
index 988652d..f8e62c0 100644
--- a/services/console-proxy/plugin/pom.xml
+++ b/services/console-proxy/plugin/pom.xml
@@ -23,7 +23,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack-service-console-proxy</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../pom.xml</relativePath>
   </parent>
 </project>
diff --git a/services/console-proxy/pom.xml b/services/console-proxy/pom.xml
index 84cfd20..1e0de55 100644
--- a/services/console-proxy/pom.xml
+++ b/services/console-proxy/pom.xml
@@ -24,7 +24,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack-services</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../pom.xml</relativePath>
   </parent>
   <build>
diff --git a/services/console-proxy/server/pom.xml b/services/console-proxy/server/pom.xml
index 9be8b4b..4d92a39 100644
--- a/services/console-proxy/server/pom.xml
+++ b/services/console-proxy/server/pom.xml
@@ -23,7 +23,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack-service-console-proxy</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../pom.xml</relativePath>
   </parent>
   <dependencies>
diff --git a/services/iam/plugin/pom.xml b/services/iam/plugin/pom.xml
index 1621c0b..3186492 100644
--- a/services/iam/plugin/pom.xml
+++ b/services/iam/plugin/pom.xml
@@ -23,7 +23,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack-service-iam</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../pom.xml</relativePath>
   </parent>
   <dependencies>
diff --git a/services/iam/server/pom.xml b/services/iam/server/pom.xml
index 81d499a..47736ce 100644
--- a/services/iam/server/pom.xml
+++ b/services/iam/server/pom.xml
@@ -23,7 +23,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack-service-iam</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../pom.xml</relativePath>
   </parent>
   <dependencies>
diff --git a/services/pom.xml b/services/pom.xml
index 7178aef..5c23fd0 100644
--- a/services/pom.xml
+++ b/services/pom.xml
@@ -24,7 +24,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../pom.xml</relativePath>
   </parent>
   <build>
diff --git a/services/secondary-storage/controller/pom.xml b/services/secondary-storage/controller/pom.xml
index 1c7c0a9..d4cf6a3 100644
--- a/services/secondary-storage/controller/pom.xml
+++ b/services/secondary-storage/controller/pom.xml
@@ -23,7 +23,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack-service-secondary-storage</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../pom.xml</relativePath>
   </parent>
   <dependencies>
diff --git a/services/secondary-storage/pom.xml b/services/secondary-storage/pom.xml
index 5d19ffb..285d647 100644
--- a/services/secondary-storage/pom.xml
+++ b/services/secondary-storage/pom.xml
@@ -24,7 +24,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack-services</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../pom.xml</relativePath>
   </parent>
   <modules>
diff --git a/services/secondary-storage/server/pom.xml b/services/secondary-storage/server/pom.xml
index 84f39dd..3ca169e 100644
--- a/services/secondary-storage/server/pom.xml
+++ b/services/secondary-storage/server/pom.xml
@@ -23,7 +23,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack-service-secondary-storage</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../pom.xml</relativePath>
   </parent>
     <dependencies>
diff --git a/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java b/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
index 420842f..b38e0b7 100644
--- a/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
+++ b/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
@@ -1585,19 +1585,28 @@
                         String line = null;
                         String uniqName = null;
                         Long size = null;
+                        Long physicalSize = null;
                         String name = null;
                         while ((line = brf.readLine()) != null) {
                             if (line.startsWith("uniquename=")) {
                                 uniqName = line.split("=")[1];
                             } else if (line.startsWith("size=")) {
+                                physicalSize = Long.parseLong(line.split("=")[1]);
+                            } else if (line.startsWith("virtualsize=")){
                                 size = Long.parseLong(line.split("=")[1]);
                             } else if (line.startsWith("filename=")) {
                                 name = line.split("=")[1];
                             }
                         }
+
+                        //fallback
+                        if (size == null) {
+                            size = physicalSize;
+                        }
+
                         tempFile.delete();
                         if (uniqName != null) {
-                            TemplateProp prop = new TemplateProp(uniqName, container + File.separator + name, size, size, true, false);
+                            TemplateProp prop = new TemplateProp(uniqName, container + File.separator + name, size, physicalSize, true, false);
                             tmpltInfos.put(uniqName, prop);
                         }
                     } catch (IOException ex)
@@ -1615,7 +1624,6 @@
             }
         }
         return tmpltInfos;
-
     }
 
     Map<String, TemplateProp> s3ListTemplate(S3TO s3) {
diff --git a/systemvm/patches/debian/config/etc/init.d/cloud-early-config b/systemvm/patches/debian/config/etc/init.d/cloud-early-config
index cd42bb0..789f929 100755
--- a/systemvm/patches/debian/config/etc/init.d/cloud-early-config
+++ b/systemvm/patches/debian/config/etc/init.d/cloud-early-config
@@ -1052,6 +1052,10 @@
       echo 0 > /var/cache/cloud/dnsmasq_managed_lease
   fi
   load_modules
+
+  #setup hourly logrotate
+  mv -n /etc/cron.daily/logrotate /etc/cron.hourly 2>&1
+
 }
 
 
diff --git a/systemvm/patches/debian/config/etc/logrotate.d/apache2 b/systemvm/patches/debian/config/etc/logrotate.d/apache2
index 3932c27..58ddb4d 100644
--- a/systemvm/patches/debian/config/etc/logrotate.d/apache2
+++ b/systemvm/patches/debian/config/etc/logrotate.d/apache2
@@ -4,6 +4,6 @@
        rotate 3
        compress
        dateext
-       size 10M
+       maxsize 10M
        notifempty
 }
diff --git a/systemvm/patches/debian/config/etc/logrotate.d/cloud b/systemvm/patches/debian/config/etc/logrotate.d/cloud
index 3fedd5e..8bda52c 100644
--- a/systemvm/patches/debian/config/etc/logrotate.d/cloud
+++ b/systemvm/patches/debian/config/etc/logrotate.d/cloud
@@ -15,8 +15,8 @@
 # specific language governing permissions and limitations
 # under the License.
 /var/log/cloud.log {
-        rotate 4
-        size 10M
+        rotate 10
+        maxsize 10M
         missingok
         notifempty
         compress
diff --git a/systemvm/patches/debian/config/etc/logrotate.d/conntrackd b/systemvm/patches/debian/config/etc/logrotate.d/conntrackd
index 1c37c4c..8b5ff66 100644
--- a/systemvm/patches/debian/config/etc/logrotate.d/conntrackd
+++ b/systemvm/patches/debian/config/etc/logrotate.d/conntrackd
@@ -1,5 +1,5 @@
 /var/log/conntrackd-stats.log {
-    size 10M
+    maxsize 10M
     rotate 2
     missingok
     compress
diff --git a/systemvm/patches/debian/config/etc/logrotate.d/dnsmasq b/systemvm/patches/debian/config/etc/logrotate.d/dnsmasq
index 99815d8..8a797e9 100644
--- a/systemvm/patches/debian/config/etc/logrotate.d/dnsmasq
+++ b/systemvm/patches/debian/config/etc/logrotate.d/dnsmasq
@@ -1,5 +1,5 @@
 /var/log/dnsmasq.log {
-    size 10M
+    maxsize 10M
     missingok
     rotate 5
     notifempty
diff --git a/systemvm/patches/debian/config/etc/logrotate.d/haproxy b/systemvm/patches/debian/config/etc/logrotate.d/haproxy
index 28da41c..4642097 100644
--- a/systemvm/patches/debian/config/etc/logrotate.d/haproxy
+++ b/systemvm/patches/debian/config/etc/logrotate.d/haproxy
@@ -2,7 +2,7 @@
     rotate 5
     missingok
     notifempty
-    size 10M
+    maxsize 10M
     postrotate
       /bin/kill -HUP `cat /var/run/rsyslog.pid 2> /dev/null` 2> /dev/null || true
     endscript
diff --git a/systemvm/patches/debian/config/etc/logrotate.d/ppp b/systemvm/patches/debian/config/etc/logrotate.d/ppp
index 624b4ae..ce02c17 100644
--- a/systemvm/patches/debian/config/etc/logrotate.d/ppp
+++ b/systemvm/patches/debian/config/etc/logrotate.d/ppp
@@ -1,5 +1,5 @@
 /var/log/ppp-connect-errors {
-	size 10M
+	maxsize 10M
 	rotate 5
 	missingok
 	notifempty
diff --git a/systemvm/patches/debian/config/etc/logrotate.d/rsyslog b/systemvm/patches/debian/config/etc/logrotate.d/rsyslog
index 5a104b3..9291494 100644
--- a/systemvm/patches/debian/config/etc/logrotate.d/rsyslog
+++ b/systemvm/patches/debian/config/etc/logrotate.d/rsyslog
@@ -1,10 +1,9 @@
 /var/log/syslog
 {
 	rotate 7
-	size 50M
+	maxsize 10M
 	missingok
 	notifempty
-	delaycompress
 	compress
 	postrotate
 		/usr/sbin/invoke-rc.d rsyslog rotate > /dev/null
@@ -25,11 +24,10 @@
 /var/log/messages
 {
 	rotate 10
-	size 50M
+	maxsize 10M
 	missingok
 	notifempty
 	compress
-	delaycompress
 	sharedscripts
 	postrotate
 		/usr/sbin/invoke-rc.d rsyslog rotate > /dev/null
diff --git a/systemvm/patches/debian/config/opt/cloud/bin/configure.py b/systemvm/patches/debian/config/opt/cloud/bin/configure.py
index 5a2a9ed..bdcfec9 100755
--- a/systemvm/patches/debian/config/opt/cloud/bin/configure.py
+++ b/systemvm/patches/debian/config/opt/cloud/bin/configure.py
@@ -659,6 +659,7 @@
 
 
         secret = CsFile(vpnsecretfilte)
+        secret.empty()
         secret.addeq(": PSK \"%s\"" %psk)
         secret.commit()
 
diff --git a/systemvm/patches/debian/config/opt/cloud/bin/cs/CsAddress.py b/systemvm/patches/debian/config/opt/cloud/bin/cs/CsAddress.py
index c280555..a16fd07 100755
--- a/systemvm/patches/debian/config/opt/cloud/bin/cs/CsAddress.py
+++ b/systemvm/patches/debian/config/opt/cloud/bin/cs/CsAddress.py
@@ -137,7 +137,7 @@
         return self.get_attr("netmask")
 
     def get_gateway(self):
-        if self.config.is_vpc() or self.config.cmdline().is_redundant():
+        if self.config.is_vpc() or not self.is_guest():
             return self.get_attr("gateway")
         else:
             return self.config.cmdline().get_guest_gw()
@@ -528,6 +528,7 @@
                 # add 'defaul via gateway' rule in the device specific routing table
                 if "gateway" in self.address and self.address["gateway"] != "None":
                     route.add_route(self.dev, self.address["gateway"])
+                route.add_network_route(self.dev, str(self.address["network"]))
 
                 if self.get_type() in ["public"]:
                     CsRule(self.dev).addRule("from " + str(self.address["network"]))
diff --git a/systemvm/patches/debian/config/opt/cloud/bin/cs/CsDhcp.py b/systemvm/patches/debian/config/opt/cloud/bin/cs/CsDhcp.py
index 23b7499..da9e616 100755
--- a/systemvm/patches/debian/config/opt/cloud/bin/cs/CsDhcp.py
+++ b/systemvm/patches/debian/config/opt/cloud/bin/cs/CsDhcp.py
@@ -89,9 +89,10 @@
                 gateway = gn.get_gateway()
             else:
                 gateway = i['gateway']
-            sline = "dhcp-option=tag:interface-%s-%s,3," % (device, idx)
-            line = "dhcp-option=tag:interface-%s-%s,3,%s" % (device, idx, gateway)
-            self.conf.search(sline, line)
+            if gateway != '0.0.0.0':
+                sline = "dhcp-option=tag:interface-%s-%s,3," % (device, idx)
+                line = "dhcp-option=tag:interface-%s-%s,3,%s" % (device, idx, gateway)
+                self.conf.search(sline, line)
             # Netmask
             netmask = ''
             if self.config.is_vpc():
diff --git a/systemvm/patches/debian/config/opt/cloud/bin/get_template_version.sh b/systemvm/patches/debian/config/opt/cloud/bin/get_template_version.sh
index 996e9dd..53bdde3 100755
--- a/systemvm/patches/debian/config/opt/cloud/bin/get_template_version.sh
+++ b/systemvm/patches/debian/config/opt/cloud/bin/get_template_version.sh
@@ -42,5 +42,6 @@
     exit
 fi
 
-echo -n `cat /etc/cloudstack-release`'&'
-cat /var/cache/cloud/cloud-scripts-signature
+release=`cat /etc/cloudstack-release`
+sig=`cat /var/cache/cloud/cloud-scripts-signature`
+echo  "${release}&${sig}"
diff --git a/systemvm/pom.xml b/systemvm/pom.xml
index 825d9fc..2503cfc 100644
--- a/systemvm/pom.xml
+++ b/systemvm/pom.xml
@@ -24,7 +24,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../pom.xml</relativePath>
   </parent>
   <properties>
diff --git a/test/integration/smoke/test_metrics_api.py b/test/integration/smoke/test_metrics_api.py
new file mode 100644
index 0000000..27c4a1b
--- /dev/null
+++ b/test/integration/smoke/test_metrics_api.py
@@ -0,0 +1,210 @@
+# 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.
+
+import marvin
+from marvin.cloudstackTestCase import *
+from marvin.cloudstackAPI import *
+from marvin.lib.utils import *
+from marvin.lib.base import *
+from marvin.lib.common import *
+from marvin.lib.utils import (random_gen)
+from nose.plugins.attrib import attr
+
+import time
+
+_multiprocess_shared_ = True
+
+class TestMetrics(cloudstackTestCase):
+
+    def setUp(self):
+        self.apiclient = self.testClient.getApiClient()
+        self.hypervisor = self.testClient.getHypervisorInfo()
+        self.dbclient = self.testClient.getDbConnection()
+        self.services = self.testClient.getParsedTestDataConfig()
+        self.zone = get_zone(self.apiclient, self.testClient.getZoneForTests())
+        self.pod = get_pod(self.apiclient, self.zone.id)
+        self.host = list_hosts(self.apiclient,
+            zoneid=self.zone.id,
+            type='Routing')[0]
+        self.cluster = self.apiclient.listClusters(listClusters.listClustersCmd())[0]
+        self.disk_offering = DiskOffering.create(
+                                    self.apiclient,
+                                    self.services["disk_offering"]
+                                    )
+        self.service_offering = ServiceOffering.create(
+            self.apiclient,
+            self.services["service_offering"]
+        )
+        self.template = get_template(
+            self.apiclient,
+            self.zone.id,
+            self.services["ostype"]
+        )
+
+        self.cleanup = []
+        self.cleanup.append(self.disk_offering)
+        self.cleanup.append(self.service_offering)
+
+    def tearDown(self):
+        try:
+            #Clean up
+            cleanup_resources(self.apiclient, self.cleanup)
+
+        except Exception as e:
+            raise Exception("Warning: Exception during cleanup : %s" % e)
+
+    @attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="false")
+    def test_list_hosts_metrics(self):
+
+        cmd = listHostsMetrics.listHostsMetricsCmd()
+        cmd.id = self.host.id
+        cmd.type = 'Routing'
+
+        host_metric = self.apiclient.listHostsMetrics(cmd)[0]
+
+        self.assertEqual(host_metric.cpuallocated, self.host.cpuallocated)
+        self.assertEqual(host_metric.memoryallocated, self.host.memoryallocated)
+
+    @attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="false")
+    def test_list_clusters_metrics(self):
+
+        cmd = listClustersMetrics.listClustersMetricsCmd()
+        cmd.id = self.cluster.id
+
+        cluster_metric = self.apiclient.listClustersMetrics(cmd)[0]
+
+        self.assertEqual(cluster_metric.id, self.cluster.id)
+        self.assertTrue(hasattr(cluster_metric, 'cpuallocated'))
+        self.assertTrue(hasattr(cluster_metric, 'cpumaxdeviation'))
+        self.assertTrue(hasattr(cluster_metric, 'memoryallocated'))
+        self.assertTrue(hasattr(cluster_metric, 'memoryused'))
+        self.assertTrue(hasattr(cluster_metric, 'memorymaxdeviation'))
+
+    @attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="false")
+    def test_list_zones_metrics(self):
+        cmd = listZonesMetrics.listZonesMetricsCmd()
+        cmd.id = self.zone.id
+
+        zone_metrics = self.apiclient.listZonesMetrics(cmd)[0]
+
+        self.assertTrue(hasattr(zone_metrics, 'cpuallocated'))
+        self.assertTrue(hasattr(zone_metrics, 'cpumaxdeviation'))
+        self.assertTrue(hasattr(zone_metrics, 'cputotal'))
+        self.assertTrue(hasattr(zone_metrics, 'cpuused'))
+        self.assertTrue(hasattr(zone_metrics, 'memoryallocated'))
+        self.assertTrue(hasattr(zone_metrics, 'memorymaxdeviation'))
+        self.assertTrue(hasattr(zone_metrics, 'memoryused'))
+
+    @attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="false")
+    def test_list_vms_metrics(self):
+        #deploy VM
+        self.small_virtual_machine = VirtualMachine.create(
+                                        self.apiclient,
+                                        self.services["virtual_machine"],
+                                        serviceofferingid=self.service_offering.id,
+                                        templateid=self.template.id,
+                                        zoneid=self.zone.id
+                                        )
+        self.cleanup.append(self.small_virtual_machine)
+
+
+        cmd = listVirtualMachinesMetrics.listVirtualMachinesMetricsCmd()
+        cmd.id = self.small_virtual_machine.id
+
+        lvmm = self.apiclient.listVirtualMachinesMetrics(cmd)[0]
+
+        self.assertEqual(lvmm.id, self.small_virtual_machine.id)
+
+        self.assertTrue(hasattr(lvmm, 'cputotal'))
+        self.assertTrue(hasattr(lvmm, 'cpuused'))
+        self.assertTrue(hasattr(lvmm, 'diskiowrite'))
+        self.assertTrue(hasattr(lvmm, 'diskkbswrite'))
+        self.assertTrue(hasattr(lvmm, 'networkread'))
+        self.assertTrue(hasattr(lvmm, 'networkwrite'))
+
+        return
+
+    @attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="false")
+    def test_list_pstorage_metrics(self):
+        #list StoragePools
+        sp = self.apiclient.listStoragePools(listStoragePools.listStoragePoolsCmd())[0]
+
+        #list StoragePoolsMetrics
+        cmd = listStoragePoolsMetrics.listStoragePoolsMetricsCmd()
+        cmd.id = sp.id
+
+        sp_metrics = self.apiclient.listStoragePoolsMetrics(cmd)[0]
+
+        self.assertEqual(sp_metrics.disksizeallocated, sp.disksizeallocated)
+        self.assertEqual(sp_metrics.state, sp.state)
+
+    @attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="false")
+    def test_list_volumes_metrics(self):
+        volume = Volume.create(
+            self.apiclient,
+            self.services['volume'],
+            zoneid=self.zone.id,
+            diskofferingid=self.disk_offering.id
+        )
+        self.cleanup.append(volume)
+
+        cmd = listVolumes.listVolumesCmd()
+        cmd.id = volume.id
+
+        lv = self.apiclient.listVolumes(cmd)[0]
+
+        cmd = listVolumesMetrics.listVolumesMetricsCmd()
+        cmd.id = lv.id
+        lvm = self.apiclient.listVolumesMetrics(cmd)[0]
+
+        self.assertEqual(lv.size, lvm.size)
+        self.assertTrue(hasattr(lvm, 'diskBytesReadRate'))
+        self.assertTrue(hasattr(lvm, 'diskBytesWriteRate'))
+        self.assertTrue(hasattr(lvm, 'diskIopsReadRate'))
+        self.assertTrue(hasattr(lvm, 'diskIopsWriteRate'))
+
+        return
+
+    @attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="false")
+    def test_list_infrastructure_metrics(self):
+        cmd = listInfrastructure.listInfrastructureCmd()
+        li = self.apiclient.listInfrastructure(cmd)
+
+        self.assertTrue(hasattr(li, 'clusters'))
+        self.assertEqual(li.clusters, len(self.apiclient.listClusters(listClusters.listClustersCmd())))
+        self.assertTrue(hasattr(li, 'hosts'))
+
+        self.assertEqual(li.hosts, len(list_hosts(self.apiclient,
+            zoneid=self.zone.id,
+            type='Routing')))
+
+        self.assertTrue(hasattr(li, 'imagestores'))
+        self.assertEqual(li.imagestores, len(self.apiclient.listImageStores(listImageStores.listImageStoresCmd())))
+
+        self.assertTrue(hasattr(li, 'pods'))
+        self.assertEqual(li.pods, len(self.apiclient.listPods(listPods.listPodsCmd())))
+
+        self.assertTrue(hasattr(li, 'routers'))
+
+        self.assertTrue(hasattr(li, 'storagepools'))
+        self.assertEqual(li.storagepools, len(self.apiclient.listStoragePools(listStoragePools.listStoragePoolsCmd())))
+
+        self.assertTrue(hasattr(li, 'zones'))
+        self.assertEqual(li.zones, len(self.apiclient.listZones(listZones.listZonesCmd())))
+
+        self.assertTrue(hasattr(li, 'systemvms'))
+        self.assertTrue(hasattr(li, 'cpusockets'))
diff --git a/test/integration/smoke/test_snapshots.py b/test/integration/smoke/test_snapshots.py
index 638b66c..a6230bc 100644
--- a/test/integration/smoke/test_snapshots.py
+++ b/test/integration/smoke/test_snapshots.py
@@ -24,12 +24,17 @@
                              Account,
                              Template,
                              ServiceOffering,
-                             Snapshot)
+                             Snapshot,
+                             StoragePool,
+                             Volume)
 from marvin.lib.common import (get_domain,
                                get_template,
                                get_zone,
+                               get_pod,
                                list_volumes,
-                               list_snapshots)
+                               list_snapshots,
+                               list_storage_pools,
+                               list_clusters)
 from marvin.lib.decoratorGenerators import skipTestIf
 
 
@@ -95,6 +100,7 @@
         # Get Zone, Domain and templates
         cls.domain = get_domain(cls.apiclient)
         cls.zone = get_zone(cls.apiclient, testClient.getZoneForTests())
+        cls.pod = get_pod(cls.apiclient, cls.zone.id)
         cls.services['mode'] = cls.zone.networktype
 
         cls.hypervisorNotSupported = False
@@ -140,7 +146,6 @@
                     mode=cls.services["mode"]
                 )
 
-            cls._cleanup.append(cls.virtual_machine)
             cls._cleanup.append(cls.service_offering)
             cls._cleanup.append(cls.account)
             cls._cleanup.append(cls.template)
@@ -255,3 +260,131 @@
         self.assertTrue(is_snapshot_on_nfs(
             self.apiclient, self.dbclient, self.config, self.zone.id, snapshot.id))
         return
+
+    @skipTestIf("hypervisorNotSupported")
+    @attr(tags=["advanced", "advancedns", "smoke"], required_hardware="true")
+    def test_02_list_snapshots_with_removed_data_store(self):
+        """Test listing volume snapshots with removed data stores
+        """
+
+        # 1) Create new Primary Storage
+        clusters = list_clusters(
+            self.apiclient,
+            zoneid=self.zone.id
+        )
+        assert isinstance(clusters,list) and len(clusters)>0
+
+        storage = StoragePool.create(self.apiclient,
+                                     self.services["nfs"],
+                                     clusterid=clusters[0].id,
+                                     zoneid=self.zone.id,
+                                     podid=self.pod.id
+                                     )
+        self.assertEqual(
+            storage.state,
+            'Up',
+            "Check primary storage state"
+        )
+        self.assertEqual(
+            storage.type,
+            'NetworkFilesystem',
+            "Check storage pool type"
+        )
+        storage_pools_response = list_storage_pools(self.apiclient,
+                                                    id=storage.id)
+        self.assertEqual(
+            isinstance(storage_pools_response, list),
+            True,
+            "Check list response returns a valid list"
+        )
+        self.assertNotEqual(
+            len(storage_pools_response),
+            0,
+            "Check list Hosts response"
+        )
+        storage_response = storage_pools_response[0]
+        self.assertEqual(
+            storage_response.id,
+            storage.id,
+            "Check storage pool ID"
+        )
+        self.assertEqual(
+            storage.type,
+            storage_response.type,
+            "Check storage pool type "
+        )
+
+        # 2) Migrate VM ROOT volume to new Primary Storage
+        volumes = list_volumes(
+            self.apiclient,
+            virtualmachineid=self.virtual_machine_with_disk.id,
+            type='ROOT',
+            listall=True
+        )
+        Volume.migrate(self.apiclient,
+                       storageid=storage.id,
+                       volumeid=volumes[0].id,
+                       livemigrate="true"
+                       )
+
+        volume_response = list_volumes(
+            self.apiclient,
+            id=volumes[0].id,
+        )
+        self.assertNotEqual(
+            len(volume_response),
+            0,
+            "Check list Volumes response"
+        )
+        volume_migrated = volume_response[0]
+        self.assertEqual(
+            volume_migrated.storageid,
+            storage.id,
+            "Check volume storage id"
+        )
+        self.cleanup.append(self.virtual_machine_with_disk)
+        self.cleanup.append(storage)
+
+        # 3) Take snapshot of VM ROOT volume
+        snapshot = Snapshot.create(
+            self.apiclient,
+            volume_migrated.id,
+            account=self.account.name,
+            domainid=self.account.domainid
+        )
+        self.debug("Snapshot created: ID - %s" % snapshot.id)
+
+        # 4) Delete VM and created Primery Storage
+        cleanup_resources(self.apiclient, self.cleanup)
+
+        # 5) List snapshot and verify it gets properly listed although Primary Storage was removed
+        snapshot_response = Snapshot.list(
+            self.apiclient,
+            id=snapshot.id
+        )
+        self.assertNotEqual(
+            len(snapshot_response),
+            0,
+            "Check list Snapshot response"
+        )
+        self.assertEqual(
+            snapshot_response[0].id,
+            snapshot.id,
+            "Check snapshot id"
+        )
+
+        # 6) Delete snapshot and verify it gets properly deleted (should not be listed)
+        self.cleanup = [snapshot]
+        cleanup_resources(self.apiclient, self.cleanup)
+
+        snapshot_response_2 = Snapshot.list(
+            self.apiclient,
+            id=snapshot.id
+        )
+        self.assertEqual(
+            snapshot_response_2,
+            None,
+            "Check list Snapshot response"
+        )
+
+        return
\ No newline at end of file
diff --git a/test/integration/smoke/test_vm_snapshots.py b/test/integration/smoke/test_vm_snapshots.py
index 5fcb80a..9295ec1 100644
--- a/test/integration/smoke/test_vm_snapshots.py
+++ b/test/integration/smoke/test_vm_snapshots.py
@@ -23,9 +23,7 @@
 from marvin.lib.base import (Account,
                              ServiceOffering,
                              VirtualMachine,
-                             VmSnapshot,
-                             Volume,
-                             Snapshot)
+                             VmSnapshot)
 from marvin.lib.common import (get_zone,
                                get_domain,
                                get_template,
@@ -279,123 +277,3 @@
             None,
             "Check list vm snapshot has be deleted"
         )
-
-class TestSnapshots(cloudstackTestCase):
-
-    @classmethod
-    def setUpClass(cls):
-        try:
-            cls._cleanup = []
-            cls.testClient = super(TestSnapshots, cls).getClsTestClient()
-            cls.api_client = cls.testClient.getApiClient()
-            cls.services = cls.testClient.getParsedTestDataConfig()
-            cls.unsupportedHypervisor = False
-            cls.hypervisor = cls.testClient.getHypervisorInfo()
-            if cls.hypervisor.lower() in (KVM.lower(), "hyperv", "lxc", XEN_SERVER.lower()):
-                cls.unsupportedHypervisor = True
-                return
-            # Get Domain, Zone, Template
-            cls.domain = get_domain(cls.api_client)
-            cls.zone = get_zone(
-                cls.api_client,
-                cls.testClient.getZoneForTests())
-            cls.template = get_template(
-                cls.api_client,
-                cls.zone.id,
-                cls.services["ostype"]
-            )
-            if cls.zone.localstorageenabled:
-                cls.storagetype = 'local'
-                cls.services["service_offerings"][
-                    "tiny"]["storagetype"] = 'local'
-            else:
-                cls.storagetype = 'shared'
-                cls.services["service_offerings"][
-                    "tiny"]["storagetype"] = 'shared'
-
-            cls.services['mode'] = cls.zone.networktype
-            cls.services["virtual_machine"]["hypervisor"] = cls.hypervisor
-            cls.services["virtual_machine"]["zoneid"] = cls.zone.id
-            cls.services["virtual_machine"]["template"] = cls.template.id
-            cls.services["custom_volume"]["zoneid"] = cls.zone.id
-            # Creating Disk offering, Service Offering and Account
-            cls.service_offering = ServiceOffering.create(
-                cls.api_client,
-                cls.services["service_offerings"]["tiny"]
-            )
-            cls._cleanup.append(cls.service_offering)
-            cls.account = Account.create(
-                cls.api_client,
-                cls.services["account"],
-                domainid=cls.domain.id
-            )
-            cls._cleanup.append(cls.account)
-        except Exception as e:
-            cls.tearDownClass()
-            raise Exception("Warning: Exception in setup : %s" % e)
-        return
-
-    def setUp(self):
-
-        self.apiclient = self.testClient.getApiClient()
-        self.dbclient = self.testClient.getDbConnection()
-        self.cleanup = []
-
-        if self.unsupportedHypervisor:
-            self.skipTest("Skipping test because unsupported\
-                    hypervisor %s" % self.hypervisor)
-
-    def tearDown(self):
-        # Clean up, terminate the created resources
-        cleanup_resources(self.apiclient, self.cleanup)
-        return
-
-    @classmethod
-    def tearDownClass(cls):
-        try:
-            cleanup_resources(cls.api_client, cls._cleanup)
-        except Exception as e:
-            raise Exception("Warning: Exception during cleanup : %s" % e)
-
-        return
-
-    @attr(tags=["advanced", "basic", "smoke"], required_hardware="true")
-    def test_01_test_vm_volume_snapshot(self):
-        """
-        @Desc: Test that Volume snapshot for root volume is not allowed
-        when VM snapshot is present for the VM
-        @Steps:
-        1: Deploy a VM and create a VM snapshot for VM
-        2: Try to create snapshot for the root volume of the VM,
-        It should expect Exception
-        """
-
-        # Creating Virtual Machine
-        virtual_machine = VirtualMachine.create(
-            self.apiclient,
-            self.services["virtual_machine"],
-            accountid=self.account.name,
-            domainid=self.account.domainid,
-            serviceofferingid=self.service_offering.id,
-        )
-
-        VmSnapshot.create(
-            self.apiclient,
-            virtual_machine.id,
-        )
-
-        volumes = Volume.list(self.apiclient,
-                              virtualmachineid=virtual_machine.id,
-                              type="ROOT",
-                              listall=True)
-
-        self.assertEqual(validateList(volumes)[0], PASS,
-                "Failed to get root volume of the VM")
-
-        volume = volumes[0]
-
-        with self.assertRaises(Exception):
-            Snapshot.create(self.apiclient,
-                            volume_id=volume.id)
-
-        return
diff --git a/test/pom.xml b/test/pom.xml
index 23d4d70..45f256b 100644
--- a/test/pom.xml
+++ b/test/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.apache.cloudstack</groupId>
         <artifactId>cloudstack</artifactId>
-        <version>4.9.2.0-SNAPSHOT</version>
+        <version>4.9.3.0-SNAPSHOT</version>
     </parent>
     <dependencies>
         <dependency>
diff --git a/tools/apidoc/gen_toc.py b/tools/apidoc/gen_toc.py
index e6ef674..0fd9775 100644
--- a/tools/apidoc/gen_toc.py
+++ b/tools/apidoc/gen_toc.py
@@ -168,7 +168,9 @@
     'CacheStore' : 'Cache Store',
     'IAM' : 'IAM',
     'OvsElement' : 'Ovs Element',
-    'StratosphereSsp' : ' Stratosphere SSP'
+    'StratosphereSsp' : ' Stratosphere SSP',
+    'Metrics' : 'Metrics',
+    'Infrastructure' : 'Metrics',
     }
 
 
diff --git a/tools/apidoc/pom.xml b/tools/apidoc/pom.xml
index 009a028..81989ba 100644
--- a/tools/apidoc/pom.xml
+++ b/tools/apidoc/pom.xml
@@ -17,7 +17,7 @@
     <parent>
         <groupId>org.apache.cloudstack</groupId>
         <artifactId>cloud-tools</artifactId>
-        <version>4.9.2.0-SNAPSHOT</version>
+        <version>4.9.3.0-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <properties>
diff --git a/tools/appliance/build.sh b/tools/appliance/build.sh
index 9ac4388..0b31cc1 100755
--- a/tools/appliance/build.sh
+++ b/tools/appliance/build.sh
@@ -433,12 +433,6 @@
 scsi0.virtualDev = "lsilogic"
 scsi0.present = "TRUE"
 vmci0.unrestricted = "false"
-ethernet0.present = "TRUE"
-ethernet0.virtualDev = "e1000"
-ethernet0.connectionType = "bridged"
-ethernet0.startConnected = "TRUE"
-ethernet0.addressType = "generated"
-ethernet0.wakeonpcktrcv = "false"
 vcpu.hotadd = "false"
 vcpu.hotremove = "false"
 firmware = "bios"
diff --git a/tools/checkstyle/pom.xml b/tools/checkstyle/pom.xml
index 65eb280..963cef4 100644
--- a/tools/checkstyle/pom.xml
+++ b/tools/checkstyle/pom.xml
@@ -24,7 +24,7 @@
     <name>Apache CloudStack Developer Tools - Checkstyle Configuration</name>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>checkstyle</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
 
     <build>
       <plugins>
diff --git a/tools/devcloud-kvm/pom.xml b/tools/devcloud-kvm/pom.xml
index 3da66a3..44db0f6 100644
--- a/tools/devcloud-kvm/pom.xml
+++ b/tools/devcloud-kvm/pom.xml
@@ -17,7 +17,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloud-tools</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../pom.xml</relativePath>
   </parent>
   <dependencies>
diff --git a/tools/devcloud/pom.xml b/tools/devcloud/pom.xml
index da43134..d49f489 100644
--- a/tools/devcloud/pom.xml
+++ b/tools/devcloud/pom.xml
@@ -17,7 +17,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloud-tools</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../pom.xml</relativePath>
   </parent>
   <dependencies>
diff --git a/tools/devcloud4/pom.xml b/tools/devcloud4/pom.xml
index 68ffeac..6395435 100644
--- a/tools/devcloud4/pom.xml
+++ b/tools/devcloud4/pom.xml
@@ -17,7 +17,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloud-tools</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../pom.xml</relativePath>
   </parent>
   <dependencies>
diff --git a/tools/marvin/pom.xml b/tools/marvin/pom.xml
index 5467637..6c7933b 100644
--- a/tools/marvin/pom.xml
+++ b/tools/marvin/pom.xml
@@ -16,7 +16,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloud-tools</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../pom.xml</relativePath>
   </parent>
 
diff --git a/tools/marvin/setup.py b/tools/marvin/setup.py
index e45aef2..4395742 100644
--- a/tools/marvin/setup.py
+++ b/tools/marvin/setup.py
@@ -27,7 +27,7 @@
         raise RuntimeError("python setuptools is required to build Marvin")
 
 
-VERSION = "4.9.2.0-SNAPSHOT"
+VERSION = "4.9.3.0-SNAPSHOT"
 
 setup(name="Marvin",
       version=VERSION,
diff --git a/tools/pom.xml b/tools/pom.xml
index 6c12d23..c4515f2 100644
--- a/tools/pom.xml
+++ b/tools/pom.xml
@@ -27,7 +27,7 @@
     <parent>
         <groupId>org.apache.cloudstack</groupId>
         <artifactId>cloudstack</artifactId>
-        <version>4.9.2.0-SNAPSHOT</version>
+        <version>4.9.3.0-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <build>
diff --git a/tools/wix-cloudstack-maven-plugin/pom.xml b/tools/wix-cloudstack-maven-plugin/pom.xml
index f91bc72..deecfcc 100644
--- a/tools/wix-cloudstack-maven-plugin/pom.xml
+++ b/tools/wix-cloudstack-maven-plugin/pom.xml
@@ -16,7 +16,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../../pom.xml</relativePath>
   </parent>
 
diff --git a/ui/index.jsp b/ui/index.jsp
index 34f6310..49290fe 100644
--- a/ui/index.jsp
+++ b/ui/index.jsp
@@ -1818,7 +1818,6 @@
         <script type="text/javascript" src="scripts/ui-custom/securityRules.js"></script>
         <script type="text/javascript" src="scripts/ui-custom/vpc.js"></script>
         <script type="text/javascript" src="scripts/vpc.js"></script>
-        <script type="text/javascript" src="scripts/network.js"></script>
         <script type="text/javascript" src="scripts/ui-custom/recurringSnapshots.js"></script>
         <script type="text/javascript" src="scripts/ui-custom/uploadVolume.js"></script>
         <script type="text/javascript" src="scripts/storage.js"></script>
@@ -1833,6 +1832,7 @@
         <script type="text/javascript" src="scripts/ui-custom/physicalResources.js"></script>
         <script type="text/javascript" src="scripts/ui-custom/zoneWizard.js"></script>
         <script type="text/javascript" src="scripts/system.js"></script>
+        <script type="text/javascript" src="scripts/network.js"></script>
         <script type="text/javascript" src="scripts/domains.js"></script>
         <script type="text/javascript" src="scripts/docs.js"></script>
         <script type="text/javascript" src="scripts/vm_snapshots.js"></script>
diff --git a/ui/scripts/metrics.js b/ui/scripts/metrics.js
index 554aab7..3152af7 100644
--- a/ui/scripts/metrics.js
+++ b/ui/scripts/metrics.js
@@ -56,15 +56,15 @@
                     label: 'label.metrics.cpu.usage',
                     collapsible: true,
                     columns: {
-                        cpuusedavg: {
+                        cpuused: {
                             label: 'label.metrics.cpu.used.avg',
                             thresholdcolor: true,
                             thresholds: {
-                                notification: 'cpunotificationthreshold',
+                                notification: 'cputhreshold',
                                 disable: 'cpudisablethreshold'
                             }
                         },
-                        cpumaxdev: {
+                        cpumaxdeviation: {
                             label: 'label.metrics.cpu.max.dev'
                         }
                     }
@@ -77,8 +77,8 @@
                             label: 'label.metrics.allocated',
                             thresholdcolor: true,
                             thresholds: {
-                                notification: 'cpunotificationthreshold',
-                                disable: 'cpudisablethreshold'
+                                notification: 'cpuallocatedthreshold',
+                                disable: 'cpuallocateddisablethreshold'
                             }
                         },
                         cputotal: {
@@ -90,15 +90,15 @@
                     label: 'label.metrics.memory.usage',
                     collapsible: true,
                     columns: {
-                        memusedavg: {
+                        memoryused: {
                             label: 'label.metrics.memory.used.avg',
                             thresholdcolor: true,
                             thresholds: {
-                                notification: 'memnotificationthreshold',
-                                disable: 'memdisablethreshold'
+                                notification: 'memorythreshold',
+                                disable: 'memorydisablethreshold'
                             }
                         },
-                        memmaxdev: {
+                        memorymaxdeviation: {
                             label: 'label.metrics.memory.max.dev'
                         }
                     }
@@ -107,15 +107,15 @@
                     label: 'label.metrics.memory.allocated',
                     collapsible: true,
                     columns: {
-                        memallocated: {
+                        memoryallocated: {
                             label: 'label.metrics.allocated',
                             thresholdcolor: true,
                             thresholds: {
-                                notification: 'memnotificationthreshold',
-                                disable: 'memdisablethreshold'
+                                notification: 'memoryallocatedthreshold',
+                                disable: 'memoryallocateddisablethreshold'
                             }
                         },
-                        memtotal: {
+                        memorytotal: {
                             label: 'label.metrics.memory.total'
                         }
                     }
@@ -125,129 +125,11 @@
                 var data = {};
                 listViewDataProvider(args, data);
                 $.ajax({
-                    url: createURL('listZones'),
+                    url: createURL('listZonesMetrics'),
                     data: data,
                     success: function(json) {
-                        var items = json.listzonesresponse.zone;
-                        if (items) {
-                            $.each(items, function(idx, zone) {
-                                items[idx].clusters = 0;
-                                items[idx].clustersUp = 0;
-                                items[idx].hosts = 0;
-                                items[idx].cpuusedavg = 0.0;
-                                items[idx].cpumaxdev = 0.0;
-                                items[idx].cpuallocated = 0.0;
-                                items[idx].cputotal = 0.0;
-                                items[idx].maxCpuUsed = 0.0;
-                                items[idx].memusedavg = 0.0;
-                                items[idx].memmaxdev = 0.0;
-                                items[idx].memallocated = 0.0;
-                                items[idx].memtotal = 0.0;
-                                items[idx].maxMemUsed = 0.0;
-
-                                // Threshold color coding
-                                items[idx].cpunotificationthreshold = 75.0;
-                                items[idx].cpudisablethreshold = 95.0;
-                                items[idx].memnotificationthreshold = 75.0;
-                                items[idx].memdisablethreshold = 95.0;
-
-                                $.ajax({
-                                    url: createURL('listClusters'),
-                                    data: {zoneid: zone.id, pagesize: -1},
-                                    success: function(json) {
-                                        if (json && json.listclustersresponse && json.listclustersresponse.cluster && json.listclustersresponse.count) {
-                                            items[idx].clusters += parseInt(json.listclustersresponse.count);
-                                            $.each(json.listclustersresponse.cluster, function(i, cluster) {
-                                                if (cluster.allocationstate == 'Enabled' && cluster.managedstate == 'Managed') {
-                                                    items[idx].clustersUp += 1;
-                                                }
-                                                $.ajax({
-                                                    url: createURL('listHosts'),
-                                                    data: {clusterid: cluster.id, type: 'routing', pagesize: -1},
-                                                    success: function(json) {
-                                                        if (json && json.listhostsresponse && json.listhostsresponse.host && json.listhostsresponse.count) {
-                                                            items[idx].hosts += parseInt(json.listhostsresponse.count);
-                                                            $.each(json.listhostsresponse.host, function(i, host) {
-                                                                if (host.hasOwnProperty('cpuused')) {
-                                                                    var hostCpuUsage = parseFloat(host.cpuused);
-                                                                    items[idx].cpuusedavg += hostCpuUsage;
-                                                                    if (hostCpuUsage > items[idx].maxCpuUsed) {
-                                                                        items[idx].maxCpuUsed = hostCpuUsage;
-                                                                    }
-                                                                }
-
-                                                                if (host.hasOwnProperty('cpuallocated')) {
-                                                                    items[idx].cpuallocated += parseFloat(host.cpuallocated.replace('%', ''));
-                                                                }
-
-                                                                if (host.hasOwnProperty('memoryused')) {
-                                                                    var hostMemoryUsage = 100.0 * parseFloat(host.memoryused) /  parseFloat(host.memorytotal);
-                                                                    items[idx].memusedavg += hostMemoryUsage;
-                                                                    if (hostMemoryUsage > items[idx].maxMemUsed) {
-                                                                        items[idx].maxMemUsed = hostMemoryUsage;
-                                                                    }
-                                                                }
-
-                                                                if (host.hasOwnProperty('memoryallocated')) {
-                                                                    items[idx].memallocated += parseFloat(100.0 * parseFloat(host.memoryallocated)/parseFloat(host.memorytotal));
-                                                                }
-                                                            });
-                                                        }
-                                                    },
-                                                    async: false
-                                                });
-                                            });
-                                        }
-                                    },
-                                    async: false
-                                });
-
-                                $.ajax({
-                                    url: createURL('listCapacity'),
-                                    data: {zoneid: zone.id},
-                                    success: function(json) {
-                                        if (json && json.listcapacityresponse && json.listcapacityresponse.capacity) {
-                                            $.each(json.listcapacityresponse.capacity, function(i, capacity) {
-                                                // CPU
-                                                if (capacity.type == 1) {
-                                                    items[idx].cputotal = parseInt(capacity.capacitytotal)/1000.0;
-                                                }
-                                                // Memory
-                                                if (capacity.type == 0) {
-                                                    items[idx].memtotal = parseInt(capacity.capacitytotal)/(1024.0*1024.0*1024.0);
-                                                }
-                                            });
-                                        }
-                                    },
-                                    async: false
-                                });
-
-                                if (items[idx].hosts != 0) {
-                                    items[idx].cpuusedavg = (items[idx].cpuusedavg / items[idx].hosts);
-                                    items[idx].cpumaxdev = (items[idx].maxCpuUsed - items[idx].cpuusedavg);
-                                    items[idx].cpuallocated = (items[idx].cpuallocated / items[idx].hosts);
-
-                                    items[idx].memusedavg = (items[idx].memusedavg / items[idx].hosts);
-                                    items[idx].memmaxdev = (items[idx].maxMemUsed - items[idx].memusedavg);
-                                    items[idx].memallocated = (items[idx].memallocated / items[idx].hosts);
-                                }
-                                // Format data
-                                items[idx].cpuusedavg = (items[idx].cpuusedavg).toFixed(2) + "%";
-                                items[idx].cpumaxdev = (items[idx].cpumaxdev).toFixed(2) + "%";
-                                items[idx].cpuallocated = (items[idx].cpuallocated).toFixed(2) + "%";
-                                items[idx].cputotal = (items[idx].cputotal).toFixed(2) + " Ghz";
-
-                                items[idx].memusedavg = (items[idx].memusedavg).toFixed(2) + "%";
-                                items[idx].memmaxdev = (items[idx].memmaxdev).toFixed(2) + "%";
-                                items[idx].memallocated = (items[idx].memallocated).toFixed(2) + "%";
-                                items[idx].memtotal = (items[idx].memtotal).toFixed(2) + " GB";
-
-                                items[idx].clusters = items[idx].clustersUp + ' / ' + items[idx].clusters;
-                                items[idx].state = items[idx].allocationstate;
-                            });
-                        }
                         args.response.success({
-                            data: items
+                            data: json.listzonesmetricsresponse.zone
                         });
                     }
                 });
@@ -290,15 +172,15 @@
                     label: 'label.metrics.cpu.usage',
                     collapsible: true,
                     columns: {
-                        cpuusedavg: {
+                        cpuused: {
                             label: 'label.metrics.cpu.used.avg',
                             thresholdcolor: true,
                             thresholds: {
-                                notification: 'cpunotificationthreshold',
+                                notification: 'cputhreshold',
                                 disable: 'cpudisablethreshold'
                             }
                         },
-                        cpumaxdev: {
+                        cpumaxdeviation: {
                             label: 'label.metrics.cpu.max.dev'
                         }
                     }
@@ -311,8 +193,8 @@
                             label: 'label.metrics.allocated',
                             thresholdcolor: true,
                             thresholds: {
-                                notification: 'cpunotificationthreshold',
-                                disable: 'cpudisablethreshold'
+                                notification: 'cpuallocatedthreshold',
+                                disable: 'cpuallocateddisablethreshold'
                             }
                         },
                         cputotal: {
@@ -324,15 +206,15 @@
                     label: 'label.metrics.memory.usage',
                     collapsible: true,
                     columns: {
-                        memusedavg: {
+                        memoryused: {
                             label: 'label.metrics.memory.used.avg',
                             thresholdcolor: true,
                             thresholds: {
-                                notification: 'memnotificationthreshold',
-                                disable: 'memdisablethreshold'
+                                notification: 'memorythreshold',
+                                disable: 'memorydisablethreshold'
                             }
                         },
-                        memmaxdev: {
+                        memorymaxdeviation: {
                             label: 'label.metrics.memory.max.dev'
                         }
                     }
@@ -341,15 +223,15 @@
                     label: 'label.metrics.memory.allocated',
                     collapsible: true,
                     columns: {
-                        memallocated: {
+                        memoryallocated: {
                             label: 'label.metrics.allocated',
                             thresholdcolor: true,
                             thresholds: {
-                                notification: 'memnotificationthreshold',
-                                disable: 'memdisablethreshold'
+                                notification: 'memoryallocatedthreshold',
+                                disable: 'memoryallocateddisablethreshold'
                             }
                         },
-                        memtotal: {
+                        memorytotal: {
                             label: 'label.metrics.memory.total'
                         }
                     }
@@ -372,154 +254,11 @@
                 }
 
                 $.ajax({
-                    url: createURL('listClusters'),
+                    url: createURL('listClustersMetrics'),
                     data: data,
                     success: function(json) {
-                        var items = json.listclustersresponse.cluster;
-                        if (items) {
-                            $.each(items, function(idx, cluster) {
-                                items[idx].hosts = 0;
-                                items[idx].hostsUp = 0;
-                                items[idx].cpuusedavg = 0.0;
-                                items[idx].cpumaxdev = 0.0;
-                                items[idx].cpuallocated = 0.0;
-                                items[idx].cputotal = 0.0;
-                                items[idx].maxCpuUsed = 0;
-                                items[idx].memusedavg = 0.0;
-                                items[idx].memmaxdev = 0.0;
-                                items[idx].memallocated = 0.0;
-                                items[idx].memtotal = 0.0;
-                                items[idx].maxMemUsed = 0.0;
-
-                                // Threshold color coding
-                                items[idx].cpunotificationthreshold = 75.0;
-                                items[idx].cpudisablethreshold = 95.0;
-                                items[idx].memnotificationthreshold = 75.0;
-                                items[idx].memdisablethreshold = 95.0;
-
-                                $.ajax({
-                                    url: createURL('listConfigurations'),
-                                    data: {clusterid: cluster.id, listAll: true},
-                                    success: function(json) {
-                                        if (json.listconfigurationsresponse && json.listconfigurationsresponse.configuration) {
-                                            $.each(json.listconfigurationsresponse.configuration, function(i, config) {
-                                                switch (config.name) {
-                                                    case 'cluster.cpu.allocated.capacity.disablethreshold':
-                                                        items[idx].cpudisablethreshold = 100 * parseFloat(config.value);
-                                                        break;
-                                                    case 'cluster.cpu.allocated.capacity.notificationthreshold':
-                                                        items[idx].cpunotificationthreshold = 100 * parseFloat(config.value);
-                                                        break;
-                                                    case 'cluster.memory.allocated.capacity.disablethreshold':
-                                                        items[idx].memdisablethreshold = 100 * parseFloat(config.value);
-                                                        break;
-                                                    case 'cluster.memory.allocated.capacity.notificationthreshold':
-                                                        items[idx].memnotificationthreshold = 100 * parseFloat(config.value);
-                                                        break;
-                                                }
-                                            });
-                                        }
-                                    },
-                                    async: false
-                                });
-
-                                $.ajax({
-                                    url: createURL('listHosts'),
-                                    data: {clusterid: cluster.id, type: 'routing', pagesize: -1},
-                                    success: function(json) {
-                                        if (json && json.listhostsresponse && json.listhostsresponse.host && json.listhostsresponse.count) {
-                                            items[idx].hosts += parseInt(json.listhostsresponse.count);
-                                            $.each(json.listhostsresponse.host, function(i, host) {
-                                                if (host.state == 'Up') {
-                                                    items[idx].hostsUp += 1;
-                                                }
-                                                if (host.hasOwnProperty('cpuused')) {
-                                                    var hostCpuUsage = parseFloat(host.cpuused);
-                                                    items[idx].cpuusedavg += hostCpuUsage;
-                                                    if (hostCpuUsage > items[idx].maxCpuUsed) {
-                                                        items[idx].maxCpuUsed = hostCpuUsage;
-                                                    }
-                                                }
-
-                                                if (host.hasOwnProperty('cpuallocated')) {
-                                                    items[idx].cpuallocated += parseFloat(host.cpuallocated.replace('%', ''));
-                                                }
-
-                                                if (host.hasOwnProperty('memoryused')) {
-                                                    var hostMemoryUsage = 100.0 * parseFloat(host.memoryused) /  parseFloat(host.memorytotal);
-                                                    items[idx].memusedavg += hostMemoryUsage;
-                                                    if (hostMemoryUsage > items[idx].maxMemUsed) {
-                                                        items[idx].maxMemUsed = hostMemoryUsage;
-                                                    }
-                                                }
-
-                                                if (host.hasOwnProperty('memoryallocated')) {
-                                                    items[idx].memallocated += parseFloat(100.0 * parseFloat(host.memoryallocated)/parseFloat(host.memorytotal));
-                                                }
-                                            });
-                                        }
-                                    },
-                                    async: false
-                                });
-
-                                $.ajax({
-                                    url: createURL('listCapacity'),
-                                    data: {clusterid: cluster.id},
-                                    success: function(json) {
-                                        if (json && json.listcapacityresponse && json.listcapacityresponse.capacity) {
-                                            $.each(json.listcapacityresponse.capacity, function(i, capacity) {
-                                                // CPU
-                                                if (capacity.type == 1) {
-                                                    items[idx].cputotal = parseInt(capacity.capacitytotal)/1000.0;
-                                                }
-                                                // Memory
-                                                if (capacity.type == 0) {
-                                                    items[idx].memtotal = parseInt(capacity.capacitytotal)/(1024.0*1024.0*1024.0);
-                                                }
-                                            });
-                                        }
-                                    },
-                                    async: false
-                                });
-
-                                if (items[idx].hosts != 0) {
-                                    items[idx].cpuusedavg = (items[idx].cpuusedavg / items[idx].hosts);
-                                    items[idx].cpumaxdev = (items[idx].maxCpuUsed - items[idx].cpuusedavg);
-                                    items[idx].cpuallocated = (items[idx].cpuallocated / items[idx].hosts);
-
-                                    items[idx].memusedavg = (items[idx].memusedavg / items[idx].hosts);
-                                    items[idx].memmaxdev = (items[idx].maxMemUsed - items[idx].memusedavg);
-                                    items[idx].memallocated = (items[idx].memallocated / items[idx].hosts);
-                                }
-
-                                // Format data
-                                items[idx].cpuusedavg = (items[idx].cpuusedavg).toFixed(2) + "%";
-                                items[idx].cpumaxdev = (items[idx].cpumaxdev).toFixed(2) + "%";
-                                items[idx].cpuallocated = (items[idx].cpuallocated).toFixed(2) + "%";
-                                items[idx].cputotal = (items[idx].cputotal).toFixed(2) + " Ghz";
-
-                                items[idx].memusedavg = (items[idx].memusedavg).toFixed(2) + "%";
-                                items[idx].memmaxdev = (items[idx].memmaxdev).toFixed(2) + "%";
-                                items[idx].memallocated = (items[idx].memallocated).toFixed(2) + "%";
-                                items[idx].memtotal = (items[idx].memtotal).toFixed(2) + " GB";
-                                items[idx].hosts = items[idx].hostsUp + ' / ' + items[idx].hosts;
-
-                                items[idx].state = items[idx].allocationstate;
-                                if (items[idx].managedstate == 'Unmanaged') {
-                                    items[idx].state = 'Unmanaged';
-                                }
-
-                                if (items[idx].managedstate == 'Managed' && items[idx].allocationstate == 'Enabled') {
-                                    items[idx].state = 'Enabled';
-                                }
-
-                                if (items[idx].managedstate == 'Managed' && items[idx].allocationstate == 'Disabled') {
-                                    items[idx].state = 'Disabled';
-                                }
-                            });
-                        }
                         args.response.success({
-                            data: items
+                            data: json.listclustersmetricsresponse.cluster
                         });
                     }
                 });
@@ -560,7 +299,7 @@
                     },
                     compact: true
                 },
-                outofbandmanagementpowerstate: {
+                powerstate: {
                     label: 'label.metrics.outofbandmanagementpowerstate',
                     converter: function (str) {
                         // For localization
@@ -580,25 +319,25 @@
                     label: 'label.metrics.cpu.usage',
                     collapsible: true,
                     columns: {
-                        cores: {
-                            label: 'label.metrics.num.cpu.cores'
+                        cpunumber: {
+                            label: 'label.metrics.num.cpu.cores',
                         },
-                        cputotal: {
+                        cputotalghz: {
                             label: 'label.metrics.cpu.total'
                         },
-                        cpuusedavg: {
+                        cpuusedghz: {
                             label: 'label.metrics.cpu.used.avg',
                             thresholdcolor: true,
                             thresholds: {
-                                notification: 'cpunotificationthreshold',
+                                notification: 'cputhreshold',
                                 disable: 'cpudisablethreshold'
                             }
                         },
-                        cpuallocated: {
+                        cpuallocatedghz: {
                             label: 'label.metrics.allocated',
                             thresholdcolor: true,
                             thresholds: {
-                                notification: 'cpuallocatednotificationthreshold',
+                                notification: 'cpuallocatedthreshold',
                                 disable: 'cpuallocateddisablethreshold'
                             }
                         }
@@ -608,23 +347,23 @@
                     label: 'label.metrics.memory.usage',
                     collapsible: true,
                     columns: {
-                        memtotal: {
+                        memorytotalgb: {
                             label: 'label.metrics.memory.total'
                         },
-                        memusedavg: {
+                        memoryusedgb: {
                             label: 'label.metrics.memory.used.avg',
                             thresholdcolor: true,
                             thresholds: {
-                                notification: 'memnotificationthreshold',
-                                disable: 'memdisablethreshold'
+                                notification: 'memorythreshold',
+                                disable: 'memorydisablethreshold'
                             }
                         },
-                        memallocated: {
+                        memoryallocatedgb: {
                             label: 'label.metrics.allocated',
                             thresholdcolor: true,
                             thresholds: {
-                                notification: 'memallocatednotificationthreshold',
-                                disable: 'memallocateddisablethreshold'
+                                notification: 'memoryallocatedthreshold',
+                                disable: 'memoryallocateddisablethreshold'
                             }
                         }
                     }
@@ -670,123 +409,11 @@
                 }
 
                 $.ajax({
-                    url: createURL('listHosts'),
+                    url: createURL('listHostsMetrics'),
                     data: data,
                     success: function(json) {
-                        var items = json.listhostsresponse.host;
-                        if (items) {
-                            $.each(items, function(idx, host) {
-                                if (host && host.outofbandmanagement) {
-                                    items[idx].outofbandmanagementpowerstate = host.outofbandmanagement.powerstate;
-                                }
-                                items[idx].cores = host.cpunumber;
-                                items[idx].cputotal = (parseFloat(host.cpunumber) * parseFloat(host.cpuspeed) / 1000.0).toFixed(2);
-                                if (host.cpuused) {
-                                    items[idx].cpuusedavg = (parseFloat(host.cpuused) * items[idx].cputotal / 100.0).toFixed(2) + ' Ghz';
-                                } else {
-                                    items[idx].cpuusedavg = '';
-                                }
-                                items[idx].cpuallocated = (parseFloat(host.cpuallocated) * items[idx].cputotal / 100.0).toFixed(2) + ' Ghz';
-                                items[idx].memtotal = (parseFloat(host.memorytotal)/(1024.0*1024.0*1024.0)).toFixed(2) + ' GB';
-                                items[idx].memallocated = (parseFloat(host.memoryallocated)/(1024.0*1024.0*1024.0)).toFixed(2) + ' GB';
-                                if (host.memoryused) {
-                                    items[idx].memusedavg = (parseFloat(host.memoryused)/(1024.0*1024.0*1024.0)).toFixed(2) + ' GB';
-                                } else {
-                                    items[idx].memusedavg = '';
-                                }
-                                if (host.networkkbsread && host.networkkbswrite) {
-                                    items[idx].networkread = (parseFloat(host.networkkbsread)/(1024.0*1024.0)).toFixed(2) + ' GB';
-                                    items[idx].networkwrite = (parseFloat(host.networkkbswrite)/(1024.0*1024.0)).toFixed(2) + ' GB';
-                                } else {
-                                    items[idx].networkread = '';
-                                    items[idx].networkwrite = '';
-                                }
-
-                                var cpuOverCommit = 1.0;
-                                var memOverCommit = 1.0;
-                                $.ajax({
-                                    url: createURL('listClusters'),
-                                    data: {clusterid: host.clusterid, listAll: true},
-                                    success: function(json) {
-                                        if (json.listclustersresponse && json.listclustersresponse.cluster) {
-                                            var cluster = json.listclustersresponse.cluster[0];
-                                            cpuOverCommit = parseFloat(cluster.cpuovercommitratio);
-                                            memOverCommit = parseFloat(cluster.memoryovercommitratio);
-                                        }
-                                    },
-                                    async: false
-                                });
-
-                                // Threshold color coding
-                                items[idx].cpunotificationthreshold = 0.75 * parseFloat(items[idx].cputotal);
-                                items[idx].cpudisablethreshold = 0.95 * parseFloat(items[idx].cputotal);
-                                items[idx].cpuallocatednotificationthreshold = 0.75 * cpuOverCommit * parseFloat(items[idx].cputotal);
-                                items[idx].cpuallocateddisablethreshold = 0.95 * cpuOverCommit * parseFloat(items[idx].cputotal);
-
-                                items[idx].memnotificationthreshold = 0.75 * parseFloat(items[idx].memtotal);
-                                items[idx].memdisablethreshold = 0.95 * parseFloat(items[idx].memtotal);
-                                items[idx].memallocatednotificationthreshold = 0.75 * memOverCommit * parseFloat(items[idx].memtotal);
-                                items[idx].memallocateddisablethreshold = 0.95 * memOverCommit * parseFloat(items[idx].memtotal);
-
-                                $.ajax({
-                                    url: createURL('listConfigurations'),
-                                    data: {clusterid: host.clusterid, listAll: true},
-                                    success: function(json) {
-                                        if (json.listconfigurationsresponse && json.listconfigurationsresponse.configuration) {
-                                            $.each(json.listconfigurationsresponse.configuration, function(i, config) {
-                                                switch (config.name) {
-                                                    case 'cluster.cpu.allocated.capacity.disablethreshold':
-                                                        items[idx].cpudisablethreshold = parseFloat(config.value) * parseFloat(items[idx].cputotal);
-                                                        items[idx].cpuallocateddisablethreshold = parseFloat(config.value) * cpuOverCommit * parseFloat(items[idx].cputotal);
-                                                        break;
-                                                    case 'cluster.cpu.allocated.capacity.notificationthreshold':
-                                                        items[idx].cpunotificationthreshold = parseFloat(config.value) * parseFloat(items[idx].cputotal);
-                                                        items[idx].cpuallocatednotificationthreshold = parseFloat(config.value) * cpuOverCommit * parseFloat(items[idx].cputotal);
-                                                        break;
-                                                    case 'cluster.memory.allocated.capacity.disablethreshold':
-                                                        items[idx].memdisablethreshold = parseFloat(config.value) * parseFloat(items[idx].memtotal);
-                                                        items[idx].memallocateddisablethreshold = parseFloat(config.value) * memOverCommit * parseFloat(items[idx].memtotal);
-                                                        break;
-                                                    case 'cluster.memory.allocated.capacity.notificationthreshold':
-                                                        items[idx].memnotificationthreshold = parseFloat(config.value) * parseFloat(items[idx].memtotal);
-                                                        items[idx].memallocatednotificationthreshold = parseFloat(config.value) * memOverCommit * parseFloat(items[idx].memtotal);
-                                                        break;
-                                                }
-                                            });
-                                        }
-                                    },
-                                    async: false
-                                });
-
-
-                                items[idx].cputotal = items[idx].cputotal + ' Ghz (x' + cpuOverCommit + ')';
-                                items[idx].memtotal = items[idx].memtotal + ' (x' + memOverCommit + ')';
-
-                                items[idx].instances = 0;
-                                items[idx].instancesUp = 0;
-                                $.ajax({
-                                    url: createURL('listVirtualMachines'),
-                                    data: {hostid: host.id, listAll: true},
-                                    success: function(json) {
-                                        if (json && json.listvirtualmachinesresponse && json.listvirtualmachinesresponse.virtualmachine) {
-                                            var vms = json.listvirtualmachinesresponse.virtualmachine;
-                                            if (vms) {
-                                                $.each(vms, function(_, vm) {
-                                                    items[idx].instances += 1;
-                                                    if (vm.state == 'Running') {
-                                                        items[idx].instancesUp += 1;
-                                                    }
-                                                });
-                                            }
-                                        }
-                                    },
-                                    async: false
-                                });
-                                items[idx].instances = items[idx].instancesUp + ' / ' + items[idx].instances;
-                            });
-                        }
                         args.response.success({
-                            data: items
+                            data: json.listhostsmetricsresponse.host
                         });
                     }
                 });
@@ -838,14 +465,14 @@
                     label: 'label.metrics.cpu.usage',
                     collapsible: true,
                     columns: {
-                        cores: {
-                            label: 'label.metrics.num.cpu.cores'
+                        cpunumber: {
+                            label: 'label.metrics.num.cpu.cores',
                         },
                         cputotal: {
                             label: 'label.metrics.cpu.total'
                         },
                         cpuused: {
-                            label: 'label.metrics.cpu.used.avg'
+                            label: 'label.metrics.cpu.used.avg',
                         }
                     }
                 },
@@ -853,7 +480,7 @@
                     label: 'label.metrics.memory.usage',
                     collapsible: true,
                     columns: {
-                        memallocated: {
+                        memorytotal: {
                             label: 'label.metrics.allocated'
                         }
                     }
@@ -874,10 +501,10 @@
                     label: 'label.metrics.disk.usage',
                     collapsible: true,
                     columns: {
-                        diskread: {
+                        diskioread: {
                             label: 'label.metrics.disk.read'
                         },
-                        diskwrite: {
+                        diskiowrite: {
                             label: 'label.metrics.disk.write'
                         },
                         diskiopstotal: {
@@ -899,45 +526,11 @@
                 }
 
                 $.ajax({
-                    url: createURL('listVirtualMachines'),
+                    url: createURL('listVirtualMachinesMetrics'),
                     data: data,
                     success: function(json) {
-                        var items = [];
-                        if (json && json.listvirtualmachinesresponse && json.listvirtualmachinesresponse.virtualmachine) {
-                            items = json.listvirtualmachinesresponse.virtualmachine;
-                            $.each(items, function(idx, vm) {
-                                items[idx].cores = vm.cpunumber;
-                                items[idx].cputotal = (parseFloat(vm.cpunumber) * parseFloat(vm.cpuspeed) / 1000.0).toFixed(1) + ' Ghz';
-                                items[idx].cpuusedavg = vm.cpuused;
-                                items[idx].cpuallocated = vm.cpuallocated;
-                                items[idx].memallocated = (parseFloat(vm.memory)/1024.0).toFixed(2) + ' GB';
-                                items[idx].networkread = (parseFloat(vm.networkkbsread)/(1024.0)).toFixed(2) + ' MB';
-                                items[idx].networkwrite = (parseFloat(vm.networkkbswrite)/(1024.0)).toFixed(2) + ' MB';
-                                items[idx].diskread = (parseFloat(vm.diskkbsread)/(1024.0)).toFixed(2) + ' MB';
-                                items[idx].diskwrite = (parseFloat(vm.diskkbswrite)/(1024.0)).toFixed(2) + ' MB';
-                                items[idx].diskiopstotal = parseFloat(vm.diskioread) + parseFloat(vm.diskiowrite);
-                                if (vm.nic && vm.nic.length > 0 && vm.nic[0].ipaddress) {
-                                    items[idx].ipaddress = vm.nic[0].ipaddress;
-                                }
-
-                                var keys = [{'cpuused': 'cpuusedavg'},
-                                            {'networkkbsread': 'networkread'},
-                                            {'networkkbswrite': 'networkwrite'},
-                                            {'diskkbsread': 'diskread'},
-                                            {'diskkbswrite': 'diskwrite'},
-                                            {'diskioread': 'diskiopstotal'}];
-                                for (keyIdx in keys) {
-                                    var map = keys[keyIdx];
-                                    var key = Object.keys(map)[0];
-                                    var uiKey = map[key];
-                                    if (!vm.hasOwnProperty(key)) {
-                                        items[idx][uiKey] = '';
-                                    }
-                                }
-                            });
-                        }
                         args.response.success({
-                            data: items
+                            data: json.listvirtualmachinesmetricsresponse.virtualmachine
                         });
                     }
                 });
@@ -974,22 +567,22 @@
                         'Expunging': 'off',
                         'Migrating': 'warning',
                         'UploadOp': 'transition',
-                        'Snapshotting': 'warning'
+                        'Snapshotting': 'warning',
                     },
                     compact: true
                 },
                 vmname: {
                     label: 'label.metrics.vm.name'
                 },
-                disksize: {
+                sizegb: {
                     label: 'label.metrics.disk.size'
                 },
                 storagetype: {
                     label: 'label.metrics.disk.storagetype'
                 },
-                storagepool: {
+                storage: {
                     label: 'label.metrics.storagepool'
-                }
+                },
             },
             dataProvider: function(args) {
                 var data = {listAll: true};
@@ -1008,25 +601,11 @@
                 }
 
                 $.ajax({
-                    url: createURL('listVolumes'),
+                    url: createURL('listVolumesMetrics'),
                     data: data,
                     success: function(json) {
-                        var items = [];
-                        if (json && json.listvolumesresponse && json.listvolumesresponse.volume) {
-                            items = json.listvolumesresponse.volume;
-                            $.each(items, function(idx, volume) {
-                                items[idx].name = volume.name;
-                                items[idx].state = volume.state;
-                                items[idx].vmname = volume.vmname;
-                                items[idx].disksize = parseFloat(volume.size)/(1024.0*1024.0*1024.0) + ' GB';
-                                items[idx].storagetype = volume.storagetype.replace(/\w\S*/g, function(txt){return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();}) + ' (' + volume.type + ')';
-                                if (volume.storage) {
-                                    items[idx].storagepool = volume.storage;
-                                }
-                            });
-                        }
                         args.response.success({
-                            data: items
+                            data: json.listvolumesmetricsresponse.volume
                         });
                     }
                 });
@@ -1062,7 +641,7 @@
                                 'ErrorInMaintenance': 'off',
                                 'PrepareForMaintenance': 'transition',
                                 'CancelMaintenance': 'warning',
-                                'Maintenance': 'warning'
+                                'Maintenance': 'warning',
                             },
                             compact: true
                         },
@@ -1078,26 +657,26 @@
                     label: 'label.metrics.disk',
                     collapsible: true,
                     columns: {
-                        disksizeused: {
+                        disksizeusedgb: {
                             label: 'label.metrics.disk.used',
                             thresholdcolor: true,
                             thresholds: {
-                                notification: 'storagenotificationthreshold',
-                                disable: 'storagedisablethreshold'
+                                notification: 'storageusagethreshold',
+                                disable: 'storageusagedisablethreshold'
                             }
                         },
-                        disksizetotal: {
+                        disksizetotalgb: {
                             label: 'label.metrics.disk.total'
                         },
-                        disksizeallocated: {
+                        disksizeallocatedgb: {
                             label: 'label.metrics.disk.allocated',
                             thresholdcolor: true,
                             thresholds: {
-                                notification: 'storageallocatednotificationthreshold',
+                                notification: 'storageallocatedthreshold',
                                 disable: 'storageallocateddisablethreshold'
                             }
                         },
-                        disksizeunallocated: {
+                        disksizeunallocatedgb: {
                             label: 'label.metrics.disk.unallocated'
                         }
                     }
@@ -1124,74 +703,11 @@
                 }
 
                 $.ajax({
-                    url: createURL('listStoragePools'),
+                    url: createURL('listStoragePoolsMetrics'),
                     data: data,
                     success: function(json) {
-                        var items = [];
-                        if (json && json.liststoragepoolsresponse && json.liststoragepoolsresponse.storagepool) {
-                            items = json.liststoragepoolsresponse.storagepool;
-                            $.each(items, function(idx, pool) {
-                                items[idx].name = pool.name;
-                                items[idx].state = pool.state;
-                                items[idx].scope = pool.scope;
-                                items[idx].type = pool.type;
-                                items[idx].overprovisionfactor = parseFloat(pool.overprovisionfactor);
-                                if (pool.disksizeused) {
-                                    items[idx].disksizeused = (parseFloat(pool.disksizeused)/(1024.0*1024.0*1024.0)).toFixed(2) + ' GB';
-                                } else {
-                                    items[idx].disksizeused = '';
-                                }
-                                items[idx].disksizetotal = parseFloat(pool.disksizetotal);
-                                items[idx].disksizeallocated = parseFloat(pool.disksizeallocated);
-                                items[idx].disksizeunallocated = (items[idx].overprovisionfactor * items[idx].disksizetotal) - items[idx].disksizeallocated;
-
-                                // Format presentation
-                                items[idx].disksizetotal = (items[idx].disksizetotal/(1024.0*1024.0*1024.0)).toFixed(2) + ' GB (x' + items[idx].overprovisionfactor + ')';
-                                items[idx].disksizeallocated = (items[idx].disksizeallocated/(1024.0*1024.0*1024.0)).toFixed(2) + ' GB';
-                                items[idx].disksizeunallocated = (items[idx].disksizeunallocated/(1024.0*1024.0*1024.0)).toFixed(2) + ' GB';
-
-                                // Threshold color coding
-                                items[idx].storagenotificationthreshold = 0.75 * parseFloat(items[idx].disksizetotal);
-                                items[idx].storagedisablethreshold = 0.95 * parseFloat(items[idx].disksizetotal);
-                                items[idx].storageallocatednotificationthreshold = 0.75 * parseFloat(items[idx].disksizetotal) * items[idx].overprovisionfactor;
-                                items[idx].storageallocateddisablethreshold = 0.95 * parseFloat(items[idx].disksizetotal) * items[idx].overprovisionfactor;
-
-
-                                var getThresholds = function(data, items, idx) {
-                                    data.listAll = true;
-                                    $.ajax({
-                                        url: createURL('listConfigurations'),
-                                        data: data,
-                                        success: function(json) {
-                                            if (json.listconfigurationsresponse && json.listconfigurationsresponse.configuration) {
-                                                $.each(json.listconfigurationsresponse.configuration, function(i, config) {
-                                                    switch (config.name) {
-                                                        case 'cluster.storage.allocated.capacity.notificationthreshold':
-                                                            items[idx].storageallocatednotificationthreshold = parseFloat(config.value) * items[idx].overprovisionfactor * parseFloat(items[idx].disksizetotal);
-                                                            break;
-                                                        case 'cluster.storage.capacity.notificationthreshold':
-                                                            items[idx].storagenotificationthreshold = parseFloat(config.value) * parseFloat(items[idx].disksizetotal);
-                                                            break;
-                                                        case 'pool.storage.allocated.capacity.disablethreshold':
-                                                            items[idx].storageallocateddisablethreshold = parseFloat(config.value) * items[idx].overprovisionfactor * parseFloat(items[idx].disksizetotal);
-                                                            break;
-                                                        case 'pool.storage.capacity.disablethreshold':
-                                                            items[idx].storagedisablethreshold = parseFloat(config.value) * parseFloat(items[idx].disksizetotal);
-                                                            break;
-                                                    }
-                                                });
-                                            }
-                                        },
-                                        async: false
-                                    });
-                                };
-                                // Update global and cluster level thresholds
-                                getThresholds({}, items, idx);
-                                getThresholds({clusterid: pool.clusterid}, items, idx);
-                            });
-                        }
                         args.response.success({
-                            data: items
+                            data: json.liststoragepoolsmetricsresponse.storagepool
                         });
                     }
                 });
diff --git a/ui/scripts/network.js b/ui/scripts/network.js
index 428807e..569e31d 100755
--- a/ui/scripts/network.js
+++ b/ui/scripts/network.js
@@ -1194,6 +1194,10 @@
                                 hiddenTabs.push('egressRules');
                             }
 
+                            if (!isAdmin()) {
+                                hiddenTabs.push("virtualRouters");
+                            }
+
                             return hiddenTabs;
                         },
 
@@ -1892,6 +1896,11 @@
                                         }
                                     });
                                 }
+                            },
+
+                            virtualRouters: {
+                                title: "label.virtual.appliances",
+                                listView: cloudStack.sections.system.subsections.virtualRouters.sections.routerNoGroup.listView
                             }
                         }
                     }
@@ -5738,8 +5747,10 @@
                         tabFilter: function(args) {
                             var hiddenTabs = [];
                             var isRouterOwner = isAdmin();
-                            if (!isRouterOwner)
+                            if (!isRouterOwner) {
                                 hiddenTabs.push("router");
+                                hiddenTabs.push("virtualRouters");
+                            }
                             return hiddenTabs;
                         },
 
@@ -5905,6 +5916,10 @@
                                         }
                                     });
                                 }
+                            },
+                            virtualRouters: {
+                                title: "label.virtual.routers",
+                                listView: cloudStack.sections.system.subsections.virtualRouters.sections.routerNoGroup.listView
                             }
                         }
                     }
diff --git a/ui/scripts/system.js b/ui/scripts/system.js
index 98403ed..b7bdd7b 100644
--- a/ui/scripts/system.js
+++ b/ui/scripts/system.js
@@ -225,322 +225,25 @@
         // System dashboard
         dashboard: {
             dataProvider: function (args) {
-                var dataFns = {
-                    zoneCount: function (data) {
-                        $.ajax({
-                            url: createURL('listZones'),
-                            data: {
-                                listAll: true,
-                                page: 1,
-                                pagesize: 1 //specifying pagesize as 1 because we don't need any embedded objects to be returned here. The only thing we need from API response is "count" property.
-                            },
-                            success: function (json) {
-                                args.response.success({
-                                    data: {
-                                        zoneCount: json.listzonesresponse.count ? json.listzonesresponse.count: 0,
-                                        zones: json.listzonesresponse.zone
-                                    }
-                                });
-                            }
+                $.ajax({
+                    url: createURL('listInfrastructure'),
+                    success: function (json) {
+                        var response = json.listinfrastructureresponse.infrastructure;
+                        var data = {};
+                        data.zoneCount = response.zones;
+                        data.podCount = response.pods;
+                        data.clusterCount = response.clusters;
+                        data.hostCount = response.hosts;
+                        data.primaryStorageCount = response.storagepools;
+                        data.secondaryStorageCount = response.imagestores;
+                        data.systemVmCount = response.systemvms;
+                        data.virtualRouterCount = response.routers;
+                        data.socketCount = response.cpusockets;
+                        args.response.success({
+                            data: data
                         });
-                        dataFns.podCount();
-                    },
-
-                    podCount: function (data) {
-                        $.ajax({
-                            url: createURL('listPods'),
-                            data: {
-                                listAll: true,
-                                page: 1,
-                                pagesize: 1 //specifying pagesize as 1 because we don't need any embedded objects to be returned here. The only thing we need from API response is "count" property.
-                            },
-                            success: function (json) {
-                                args.response.success({
-                                    data: {
-                                        podCount: json.listpodsresponse.count ? json.listpodsresponse.count: 0
-                                    }
-                                });
-                            }
-                        });
-                        dataFns.clusterCount();
-                    },
-
-                    clusterCount: function (data) {
-                        $.ajax({
-                            url: createURL('listClusters'),
-                            data: {
-                                listAll: true,
-                                page: 1,
-                                pagesize: 1 //specifying pagesize as 1 because we don't need any embedded objects to be returned here. The only thing we need from API response is "count" property.
-                            },
-                            success: function (json) {
-                                args.response.success({
-                                    data: {
-                                        clusterCount: json.listclustersresponse.count ? json.listclustersresponse.count: 0
-                                    }
-                                });
-                            }
-                        });
-                        dataFns.hostCount();
-                    },
-
-                    hostCount: function (data) {
-                        var data2 = {
-                            type: 'routing',
-                            listAll: true,
-                            page: 1,
-                            pagesize: 1 //specifying pagesize as 1 because we don't need any embedded objects to be returned here. The only thing we need from API response is "count" property.
-                        };
-                        $.ajax({
-                            url: createURL('listHosts'),
-                            data: data2,
-                            success: function (json) {
-                                args.response.success({
-                                    data: {
-                                        hostCount: json.listhostsresponse.count ? json.listhostsresponse.count: 0
-                                    }
-                                });
-                            }
-                        });
-                        dataFns.primaryStorageCount();
-                    },
-
-                    primaryStorageCount: function (data) {
-                        var data2 = {
-                            listAll: true,
-                            page: 1,
-                            pagesize: 1 //specifying pagesize as 1 because we don't need any embedded objects to be returned here. The only thing we need from API response is "count" property.
-                        };
-                        $.ajax({
-                            url: createURL('listStoragePools'),
-                            data: data2,
-                            success: function (json) {
-                                args.response.success({
-                                    data: {
-                                        primaryStorageCount: json.liststoragepoolsresponse.count ? json.liststoragepoolsresponse.count: 0
-                                    }
-                                });
-                            }
-                        });
-                        dataFns.secondaryStorageCount();
-                    },
-
-                    secondaryStorageCount: function (data) {
-                        var data2 = {
-                            type: 'SecondaryStorage',
-                            listAll: true,
-                            page: 1,
-                            pagesize: 1 //specifying pagesize as 1 because we don't need any embedded objects to be returned here. The only thing we need from API response is "count" property.
-                        };
-                        $.ajax({
-                            url: createURL('listImageStores'),
-                            data: data2,
-                            success: function (json) {
-                                args.response.success({
-                                    data: {
-                                        secondaryStorageCount: json.listimagestoresresponse.imagestore ? json.listimagestoresresponse.count: 0
-                                    }
-                                });
-                            }
-                        });
-                        dataFns.systemVmCount();
-                    },
-
-                    systemVmCount: function (data) {
-                        $.ajax({
-                            url: createURL('listSystemVms'),
-                            data: {
-                                listAll: true,
-                                page: 1,
-                                pagesize: 1 //specifying pagesize as 1 because we don't need any embedded objects to be returned here. The only thing we need from API response is "count" property.
-                            },
-                            success: function (json) {
-                                args.response.success({
-                                    data: {
-                                        systemVmCount: json.listsystemvmsresponse.count ? json.listsystemvmsresponse.count: 0
-                                    }
-                                });
-                            }
-                        });
-                        dataFns.virtualRouterCount();
-                    },
-
-                    virtualRouterCount: function (data) {
-                        var data2 = {
-                            listAll: true,
-                            page: 1,
-                            pagesize: 1 //specifying pagesize as 1 because we don't need any embedded objects to be returned here. The only thing we need from API response is "count" property.
-                        };
-                        $.ajax({
-                            url: createURL('listRouters'),
-                            data: data2,
-                            success: function (json) {
-                                var total1 = json.listroutersresponse.count ? json.listroutersresponse.count: 0;
-                                var total2 = 0; //reset
-
-                                /*
-                                 * In project view, the first listRotuers API(without projectid=-1) will return the same objects as the second listRouters API(with projectid=-1),
-                                 * because in project view, all API calls are appended with projectid=[projectID].
-                                 * Therefore, we only call the second listRouters API(with projectid=-1) in non-project view.
-                                 */
-                                if (cloudStack.context && cloudStack.context.projects == null) { //non-project view
-                                var data3 = {
-                                    listAll: true,
-                                        projectid: -1,
-                                    page: 1,
-                                    pagesize: 1 //specifying pagesize as 1 because we don't need any embedded objects to be returned here. The only thing we need from API response is "count" property.
-                                };
-                                $.ajax({
-                                    url: createURL('listRouters'),
-                                    data: data3,
-                                        async: false,
-                                    success: function (json) {
-                                            total2 = json.listroutersresponse.count ? json.listroutersresponse.count : 0;
-                                        }
-                                    });
-                                }
-
-                                        args.response.success({
-                                            data: {
-                                                virtualRouterCount: (total1 + total2)
-                                            }
-                                        });
-                                    }
-                                });
-                                dataFns.capacity();
-                    },
-
-                    capacity: function (data) {
-                        $.ajax({
-                            url: createURL('listCapacity'),
-                            success: function (json) {
-                                var capacities = json.listcapacityresponse.capacity;
-                                if(capacities) {
-                                    var capacityTotal = function (id, converter) {
-                                        var capacity = $.grep(capacities, function (capacity) {
-                                            return capacity.type == id;
-                                        })[0];
-
-                                        var total = capacity ? capacity.capacitytotal: 0;
-
-                                        if (converter) {
-                                            return converter(total);
-                                        }
-
-                                        return total;
-                                    };
-
-                                    args.response.success({
-                                        data: {
-                                           cpuCapacityTotal: capacityTotal(1, cloudStack.converters.convertHz),
-                                           memCapacityTotal: capacityTotal(0, cloudStack.converters.convertBytes),
-                                           storageCapacityTotal: capacityTotal(2, cloudStack.converters.convertBytes)
-                                        }
-                                    });
-
-                                } else {
-
-                                    args.response.success({
-                                        data: {
-                                            cpuCapacityTotal: cloudStack.converters.convertHz(0),
-                                            memCapacityTotal: cloudStack.converters.convertBytes(0),
-                                            storageCapacityTotal: cloudStack.converters.convertBytes(0)
-                                        }
-                                    });
-
-                                }
-                            }
-                        });
-
-                       dataFns.socketInfo();
-                    },
-
-                    socketInfo: function (data) {
-                        var socketCount = 0;
-
-                        function listHostFunction(hypervisor, pageSizeValue) {
-                            var deferred = $.Deferred();
-                            var totalHostCount = 0;
-                            var returnedHostCount = 0;
-                            var returnedHostCpusocketsSum = 0;
-
-                            var callListHostsWithPage = function(page) {
-                                $.ajax({
-                                    url: createURL('listHosts'),
-                                    data: {
-                                        type: 'routing',
-                                        hypervisor: hypervisor,
-                                        page: page,
-                                        details: 'min',
-                                        pagesize: pageSizeValue
-                                    },
-                                    success: function (json) {
-                                        if (json.listhostsresponse.count == undefined) {
-                                            deferred.resolve();
-                                            return;
-                                        }
-
-                                        totalHostCount = json.listhostsresponse.count;
-                                        returnedHostCount += json.listhostsresponse.host.length;
-
-                                        var items = json.listhostsresponse.host;
-                                        for (var i = 0; i < items.length; i++) {
-                                            if (items[i].cpusockets != undefined && isNaN(items[i].cpusockets) == false) {
-                                                returnedHostCpusocketsSum += items[i].cpusockets;
-                                            }
-                                        }
-
-                                        if (returnedHostCount < totalHostCount) {
-                                            callListHostsWithPage(++page);
-                                        } else {
-                                            socketCount += returnedHostCpusocketsSum;
-                                            deferred.resolve();
-                                        }
-                                    }
-                                });
-                            }
-
-                            callListHostsWithPage(1);
-
-                            return deferred;
-
-                        }
-
-                        $.ajax({
-                            url: createURL('listConfigurations'),
-                            data: {
-                                name : 'default.page.size'
-                            },
-                            success: function (json) {
-                                pageSizeValue = json.listconfigurationsresponse.configuration[0].value;
-                                if(!pageSizeValue) {
-                                    return;
-                                }
-                                $.ajax({
-                                    url: createURL('listHypervisors'),
-                                    success: function (json) {
-                                        var deferredArray = [];
-
-                                        $(json.listhypervisorsresponse.hypervisor).map(function (index, hypervisor) {
-                                             deferredArray.push(listHostFunction(hypervisor.name, pageSizeValue));
-                                        });
-
-                                        $.when.apply(null, deferredArray).then(function(){
-                                            args.response.success({
-                                                data: {
-                                                  socketCount: socketCount
-                                                }
-                                            });
-                                        });
-                                    }
-                                });
-                            }
-                        });
-
                     }
-                };
-
-                dataFns.zoneCount();
+                });
             }
         },
 
@@ -9769,6 +9472,16 @@
                                              domainid: args.context.routerGroupByAccount[0].domainid
                                         })
                                     }
+                                    if ("networks" in args.context) {
+                                       $.extend(data2, {
+                                             networkid: args.context.networks[0].id
+                                       })
+                                    }
+                                    if ("vpc" in args.context) {
+                                       $.extend(data2, {
+                                             vpcid: args.context.vpc[0].id
+                                       })
+                                    }
                                 }
 
                                 var routers =[];
diff --git a/ui/scripts/templates.js b/ui/scripts/templates.js
index 96ef43a..ce78564 100644
--- a/ui/scripts/templates.js
+++ b/ui/scripts/templates.js
@@ -1447,7 +1447,11 @@
                                                  label: 'label.action.delete.template',
                                                  messages: {
                                                      confirm: function(args) {
-                                                         return 'message.action.delete.template';
+                                                         if(args.context.templates[0].crossZones == true) {
+                                                             return 'message.action.delete.template.for.all.zones';
+                                                         } else {
+                                                             return 'message.action.delete.template';
+                                                         }
                                                      },
                                                      notification: function(args) {
                                                          return 'label.action.delete.template';
diff --git a/ui/scripts/ui/widgets/listView.js b/ui/scripts/ui/widgets/listView.js
index e61f43c..fed6194 100644
--- a/ui/scripts/ui/widgets/listView.js
+++ b/ui/scripts/ui/widgets/listView.js
@@ -1245,12 +1245,11 @@
 
                 if (field.thresholdcolor && field.thresholds) {
                     if ((field.thresholds.disable in dataItem) && (field.thresholds.notification in dataItem)) {
-                        var disableThreshold = parseFloat(dataItem[field.thresholds.disable]);
-                        var notificationThreshold = parseFloat(dataItem[field.thresholds.notification]);
-                        var value = parseFloat(content);
-                        if (value >= disableThreshold) {
+                        var disableThreshold = dataItem[field.thresholds.disable];
+                        var notificationThreshold = dataItem[field.thresholds.notification];
+                        if (disableThreshold) {
                             $td.addClass('alert-disable-threshold');
-                        } else if (value >= notificationThreshold) {
+                        } else if (notificationThreshold) {
                             $td.addClass('alert-notification-threshold');
                         }
                     }
diff --git a/usage/pom.xml b/usage/pom.xml
index b275419..dda50ac 100644
--- a/usage/pom.xml
+++ b/usage/pom.xml
@@ -15,7 +15,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
   </parent>
   <dependencies>
     <dependency>
diff --git a/utils/conf/db.properties b/utils/conf/db.properties
index c7aeaad..4182811 100644
--- a/utils/conf/db.properties
+++ b/utils/conf/db.properties
@@ -44,7 +44,7 @@
 db.cloud.timeBetweenEvictionRunsMillis=40000
 db.cloud.minEvictableIdleTimeMillis=240000
 db.cloud.poolPreparedStatements=false
-db.cloud.url.params=prepStmtCacheSize=517&cachePrepStmts=true&prepStmtCacheSqlLimit=4096
+db.cloud.url.params=prepStmtCacheSize=517&cachePrepStmts=true&prepStmtCacheSqlLimit=4096&sessionVariables=sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'
 
 # usage database settings
 db.usage.username=cloud
diff --git a/utils/pom.xml b/utils/pom.xml
index 9f9b4cc..2250907 100755
--- a/utils/pom.xml
+++ b/utils/pom.xml
@@ -26,7 +26,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
     <relativePath>../pom.xml</relativePath>
   </parent>
   <dependencies>
@@ -208,7 +208,6 @@
           <excludes>
             <exclude>com/cloud/utils/testcase/*TestCase*</exclude>
             <exclude>com/cloud/utils/db/*Test*</exclude>
-            <exclude>com/cloud/utils/testcase/NioTest.java</exclude>
           </excludes>
         </configuration>
       </plugin>
diff --git a/utils/src/main/java/com/cloud/utils/StringUtils.java b/utils/src/main/java/com/cloud/utils/StringUtils.java
index 71cebe1..9554e87 100644
--- a/utils/src/main/java/com/cloud/utils/StringUtils.java
+++ b/utils/src/main/java/com/cloud/utils/StringUtils.java
@@ -296,8 +296,8 @@
     public static <T> List<T> applyPagination(final List<T> originalList, final Long startIndex, final Long pageSizeVal) {
         // Most likely pageSize will never exceed int value, and we need integer to partition the listToReturn
         final boolean applyPagination = startIndex != null && pageSizeVal != null
-                && startIndex <= Integer.MAX_VALUE && startIndex >= Integer.MIN_VALUE && pageSizeVal <= Integer.MAX_VALUE
-                && pageSizeVal >= Integer.MIN_VALUE;
+                && startIndex <= Integer.MAX_VALUE && startIndex >= 0 && pageSizeVal <= Integer.MAX_VALUE
+                && pageSizeVal > 0;
                 List<T> listWPagination = null;
                 if (applyPagination) {
                     listWPagination = new ArrayList<>();
diff --git a/utils/src/main/java/com/cloud/utils/net/NetUtils.java b/utils/src/main/java/com/cloud/utils/net/NetUtils.java
index a73813c..7b48fc0 100644
--- a/utils/src/main/java/com/cloud/utils/net/NetUtils.java
+++ b/utils/src/main/java/com/cloud/utils/net/NetUtils.java
@@ -875,7 +875,7 @@
         Long[] cidrBLong = cidrToLong(cidrB);
 
         long shift = MAX_CIDR - cidrBLong[1];
-        return cidrALong[0] >> shift == cidrBLong[0] >> shift;
+        return (cidrALong[0] >> shift == cidrBLong[0] >> shift) && (cidrALong[1] >= cidrBLong[1]);
     }
 
     static boolean areCidrsNotEmpty(String cidrA, String cidrB) {
@@ -1141,22 +1141,26 @@
         // 10.0.0.0 - 10.255.255.255 (10/8 prefix)
         // 172.16.0.0 - 172.31.255.255 (172.16/12 prefix)
         // 192.168.0.0 - 192.168.255.255 (192.168/16 prefix)
-
-        final String cidr1 = "10.0.0.0/8";
-        final String cidr2 = "172.16.0.0/12";
-        final String cidr3 = "192.168.0.0/16";
+        // RFC 6598 - The IETF detailed shared address space for use in ISP CGN
+        // deployments and NAT devices that can handle the same addresses occurring both on inbound and outbound interfaces.
+        // ARIN returned space to the IANA as needed for this allocation.
+        // The allocated address block is 100.64.0.0/10
+        final String[] allowedNetBlocks = {"10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16", "100.64.0.0/10"};
 
         if (!isValidCIDR(cidr)) {
             s_logger.warn("Cidr " + cidr + " is not valid");
             return false;
         }
 
-        if (isNetworkAWithinNetworkB(cidr, cidr1) || isNetworkAWithinNetworkB(cidr, cidr2) || isNetworkAWithinNetworkB(cidr, cidr3)) {
-            return true;
-        } else {
-            s_logger.warn("cidr " + cidr + " is not RFC 1918 compliant");
-            return false;
+        for (String block: allowedNetBlocks) {
+            if (isNetworkAWithinNetworkB(cidr, block)) {
+                return true;
+            }
         }
+
+        // not in allowedNetBlocks - return false
+        s_logger.warn("cidr " + cidr + " is not RFC 1918 or 6598 compliant");
+        return false;
     }
 
     public static boolean verifyInstanceName(final String instanceName) {
@@ -1165,7 +1169,6 @@
             s_logger.warn("Instance name can not contain hyphen, spaces and \"+\" char");
             return false;
         }
-
         return true;
     }
 
diff --git a/utils/src/main/java/com/cloud/utils/nio/NioConnection.java b/utils/src/main/java/com/cloud/utils/nio/NioConnection.java
index 630b2dd..ce03246 100644
--- a/utils/src/main/java/com/cloud/utils/nio/NioConnection.java
+++ b/utils/src/main/java/com/cloud/utils/nio/NioConnection.java
@@ -98,10 +98,9 @@
         }
         _isStartup = true;
 
-        _threadExecutor = Executors.newSingleThreadExecutor();
-        _futureTask = _threadExecutor.submit(this);
-
+        _threadExecutor = Executors.newSingleThreadExecutor(new NamedThreadFactory(this._name + "-NioConnectionHandler"));
         _isRunning = true;
+        _futureTask = _threadExecutor.submit(this);
     }
 
     public void stop() {
diff --git a/utils/src/test/java/com/cloud/utils/net/NetUtilsTest.java b/utils/src/test/java/com/cloud/utils/net/NetUtilsTest.java
index 490d0df..f10c44b 100644
--- a/utils/src/test/java/com/cloud/utils/net/NetUtilsTest.java
+++ b/utils/src/test/java/com/cloud/utils/net/NetUtilsTest.java
@@ -301,9 +301,15 @@
 
     @Test
     public void testValidateGuestCidr() throws Exception {
-        final String guestCidr = "192.168.1.0/24";
+        final String[] validCidrs = {"10.1.1.1/16", "172.16.1.0/16", "192.168.1.0/24", "100.64.1.0/24"};
+        final String[] invalidCidrs = {"172.33.1.0/16", "100.128.1.0/10"};
 
-        assertTrue(NetUtils.validateGuestCidr(guestCidr));
+        for (String cidr: validCidrs) {
+            assertTrue(NetUtils.validateGuestCidr(cidr));
+        }
+        for (String cidr: invalidCidrs) {
+            assertFalse(NetUtils.validateGuestCidr(cidr));
+        }
     }
 
     @Test
@@ -505,6 +511,19 @@
     }
 
     @Test
+    public void testIsNetworkAWithinNetworkB() {
+        assertTrue(NetUtils.isNetworkAWithinNetworkB("192.168.30.0/24", "192.168.30.0/23"));
+        assertTrue(NetUtils.isNetworkAWithinNetworkB("192.168.30.0/24", "192.168.30.0/22"));
+        assertFalse(NetUtils.isNetworkAWithinNetworkB("192.168.30.0/23", "192.168.30.0/24"));
+        assertFalse(NetUtils.isNetworkAWithinNetworkB("192.168.30.0/22", "192.168.30.0/24"));
+        assertTrue(NetUtils.isNetworkAWithinNetworkB("192.168.28.0/24", "192.168.28.0/23"));
+        assertTrue(NetUtils.isNetworkAWithinNetworkB("192.168.28.0/24", "192.168.28.0/22"));
+        assertFalse(NetUtils.isNetworkAWithinNetworkB("192.168.28.0/23", "192.168.28.0/24"));
+        assertFalse(NetUtils.isNetworkAWithinNetworkB("192.168.28.0/22", "192.168.28.0/24"));
+        assertTrue(NetUtils.isNetworkAWithinNetworkB("192.168.30.0/24", "192.168.28.0/22"));
+    }
+
+    @Test
     public void testIsNetworksOverlapWithEmptyValues() {
         assertEquals(false, NetUtils.isNetworksOverlap("", null));
     }
diff --git a/vmware-base/pom.xml b/vmware-base/pom.xml
index 0ac9952..abef855 100644
--- a/vmware-base/pom.xml
+++ b/vmware-base/pom.xml
@@ -24,7 +24,7 @@
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack</artifactId>
-    <version>4.9.2.0-SNAPSHOT</version>
+    <version>4.9.3.0-SNAPSHOT</version>
   </parent>
   <dependencies>
     <dependency>
diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/mo/ClusterMO.java b/vmware-base/src/com/cloud/hypervisor/vmware/mo/ClusterMO.java
index b5f0500..a6e4285 100644
--- a/vmware-base/src/com/cloud/hypervisor/vmware/mo/ClusterMO.java
+++ b/vmware-base/src/com/cloud/hypervisor/vmware/mo/ClusterMO.java
@@ -22,16 +22,20 @@
 import java.util.HashMap;
 import java.util.List;
 
+import org.apache.commons.lang.StringUtils;
 import org.apache.log4j.Logger;
 
 import com.google.gson.Gson;
 import com.vmware.vim25.ArrayOfHostIpRouteEntry;
+import com.vmware.vim25.ArrayUpdateOperation;
 import com.vmware.vim25.ClusterComputeResourceSummary;
 import com.vmware.vim25.ClusterConfigInfoEx;
 import com.vmware.vim25.ClusterDasConfigInfo;
+import com.vmware.vim25.ClusterDasVmSettingsRestartPriority;
 import com.vmware.vim25.ClusterHostRecommendation;
 import com.vmware.vim25.ComputeResourceSummary;
 import com.vmware.vim25.CustomFieldStringValue;
+import com.vmware.vim25.DasVmPriority;
 import com.vmware.vim25.DatastoreInfo;
 import com.vmware.vim25.DynamicProperty;
 import com.vmware.vim25.GuestOsDescriptor;
@@ -49,6 +53,10 @@
 import com.vmware.vim25.TraversalSpec;
 import com.vmware.vim25.VirtualMachineConfigOption;
 import com.vmware.vim25.VirtualMachineConfigSpec;
+import com.vmware.vim25.ClusterDasVmConfigInfo;
+import com.vmware.vim25.ClusterDasVmConfigSpec;
+import com.vmware.vim25.ClusterDasVmSettings;
+import com.vmware.vim25.ClusterConfigSpecEx;
 
 import com.cloud.hypervisor.vmware.util.VmwareContext;
 import com.cloud.hypervisor.vmware.util.VmwareHelper;
@@ -77,9 +85,118 @@
 
     @Override
     public ClusterDasConfigInfo getDasConfig() throws Exception {
-        // Note getDynamicProperty() with "configurationEx.dasConfig" does not work here because of that dasConfig is a property in subclass
+        ClusterConfigInfoEx configInfo = getClusterConfigInfo();
+        if (configInfo != null) {
+            // Note getDynamicProperty() with "configurationEx.dasConfig" does not work here because of that dasConfig is a property in subclass
+            return configInfo.getDasConfig();
+        }
+
+        return null;
+    }
+
+    private ClusterConfigInfoEx getClusterConfigInfo() throws Exception {
         ClusterConfigInfoEx configInfo = (ClusterConfigInfoEx)_context.getVimClient().getDynamicProperty(_mor, "configurationEx");
-        return configInfo.getDasConfig();
+        return configInfo;
+    }
+
+    @Override
+    public boolean isHAEnabled() throws Exception {
+        ClusterDasConfigInfo dasConfig = getDasConfig();
+        if (dasConfig != null && dasConfig.isEnabled() != null && dasConfig.isEnabled().booleanValue()) {
+            return true;
+        }
+
+        return false;
+    }
+
+    private String getRestartPriorityForVM(VirtualMachineMO vmMo) throws Exception {
+        if (vmMo == null) {
+            s_logger.debug("Failed to get restart priority for VM, invalid VM object reference");
+            return null;
+        }
+
+        ManagedObjectReference vmMor = vmMo.getMor();
+        if (vmMor == null || !vmMor.getType().equals("VirtualMachine")) {
+            s_logger.debug("Failed to get restart priority for VM: " + vmMo.getName() + ", invalid VM object reference");
+            return null;
+        }
+
+        ClusterConfigInfoEx configInfo = getClusterConfigInfo();
+        if (configInfo == null) {
+            s_logger.debug("Failed to get restart priority for VM: " + vmMo.getName() + ", no cluster config information");
+            return null;
+        }
+
+        List<ClusterDasVmConfigInfo> dasVmConfig = configInfo.getDasVmConfig();
+        for (int dasVmConfigIndex = 0; dasVmConfigIndex < dasVmConfig.size(); dasVmConfigIndex++) {
+            ClusterDasVmConfigInfo dasVmConfigInfo = dasVmConfig.get(dasVmConfigIndex);
+            if (dasVmConfigInfo != null && dasVmConfigInfo.getKey().getValue().equals(vmMor.getValue())) {
+                DasVmPriority dasVmPriority = dasVmConfigInfo.getRestartPriority();
+                if (dasVmPriority != null) {
+                    return dasVmPriority.value();
+                } else {
+                    //VM uses cluster restart priority when DasVmPriority for the VM is null.
+                    return ClusterDasVmSettingsRestartPriority.CLUSTER_RESTART_PRIORITY.value();
+                }
+            }
+        }
+
+        s_logger.debug("VM: " + vmMo.getName() + " uses default restart priority in the cluster: " + getName());
+        return null;
+    }
+
+    @Override
+    public void setRestartPriorityForVM(VirtualMachineMO vmMo, String priority) throws Exception {
+        if (vmMo == null || StringUtils.isBlank(priority)) {
+            return;
+        }
+
+        if (!isHAEnabled()) {
+            s_logger.debug("Couldn't set restart priority for VM: " + vmMo.getName() + ", HA disabled in the cluster");
+            return;
+        }
+
+        ManagedObjectReference vmMor = vmMo.getMor();
+        if (vmMor == null || !vmMor.getType().equals("VirtualMachine")) {
+            s_logger.debug("Failed to set restart priority for VM: " + vmMo.getName() + ", invalid VM object reference");
+            return;
+        }
+
+        String currentVmRestartPriority = getRestartPriorityForVM(vmMo);
+        if (StringUtils.isNotBlank(currentVmRestartPriority) && currentVmRestartPriority.equalsIgnoreCase(priority)) {
+            return;
+        }
+
+        ClusterDasVmSettings clusterDasVmSettings = new ClusterDasVmSettings();
+        clusterDasVmSettings.setRestartPriority(priority);
+
+        ClusterDasVmConfigInfo clusterDasVmConfigInfo = new ClusterDasVmConfigInfo();
+        clusterDasVmConfigInfo.setKey(vmMor);
+        clusterDasVmConfigInfo.setDasSettings(clusterDasVmSettings);
+
+        ClusterDasVmConfigSpec clusterDasVmConfigSpec = new ClusterDasVmConfigSpec();
+        clusterDasVmConfigSpec.setOperation((StringUtils.isNotBlank(currentVmRestartPriority)) ? ArrayUpdateOperation.EDIT : ArrayUpdateOperation.ADD);
+        clusterDasVmConfigSpec.setInfo(clusterDasVmConfigInfo);
+
+        ClusterConfigSpecEx clusterConfigSpecEx = new ClusterConfigSpecEx();
+        ClusterDasConfigInfo clusterDasConfigInfo = new ClusterDasConfigInfo();
+        clusterConfigSpecEx.setDasConfig(clusterDasConfigInfo);
+        clusterConfigSpecEx.getDasVmConfigSpec().add(clusterDasVmConfigSpec);
+
+        ManagedObjectReference morTask = _context.getService().reconfigureComputeResourceTask(_mor, clusterConfigSpecEx, true);
+
+        boolean result = _context.getVimClient().waitForTask(morTask);
+
+        if (result) {
+            _context.waitForTaskProgressDone(morTask);
+
+            if (s_logger.isTraceEnabled())
+                s_logger.trace("vCenter API trace - setRestartPriority done(successfully)");
+        } else {
+            if (s_logger.isTraceEnabled())
+                s_logger.trace("vCenter API trace - setRestartPriority done(failed)");
+            s_logger.error("Set restart priority failed for VM: " + vmMo.getName() + " due to " + TaskMO.getTaskFailureInfo(_context, morTask));
+        }
     }
 
     @Override
diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/mo/HostMO.java b/vmware-base/src/com/cloud/hypervisor/vmware/mo/HostMO.java
index c008e6b..5f64e83 100644
--- a/vmware-base/src/com/cloud/hypervisor/vmware/mo/HostMO.java
+++ b/vmware-base/src/com/cloud/hypervisor/vmware/mo/HostMO.java
@@ -144,6 +144,26 @@
     }
 
     @Override
+    public boolean isHAEnabled() throws Exception {
+        ManagedObjectReference morParent = getParentMor();
+        if (morParent.getType().equals("ClusterComputeResource")) {
+            ClusterMO clusterMo = new ClusterMO(_context, morParent);
+            return clusterMo.isHAEnabled();
+        }
+
+        return false;
+    }
+
+    @Override
+    public void setRestartPriorityForVM(VirtualMachineMO vmMo, String priority) throws Exception {
+        ManagedObjectReference morParent = getParentMor();
+        if (morParent.getType().equals("ClusterComputeResource")) {
+            ClusterMO clusterMo = new ClusterMO(_context, morParent);
+            clusterMo.setRestartPriorityForVM(vmMo, priority);
+        }
+    }
+
+    @Override
     public String getHyperHostDefaultGateway() throws Exception {
         List<HostIpRouteEntry> entries = getHostIpRouteEntries();
         for (HostIpRouteEntry entry : entries) {
diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/mo/HypervisorHostHelper.java b/vmware-base/src/com/cloud/hypervisor/vmware/mo/HypervisorHostHelper.java
index 71c007d..ef3f0ae 100644
--- a/vmware-base/src/com/cloud/hypervisor/vmware/mo/HypervisorHostHelper.java
+++ b/vmware-base/src/com/cloud/hypervisor/vmware/mo/HypervisorHostHelper.java
@@ -16,17 +16,6 @@
 // under the License.
 package com.cloud.hypervisor.vmware.mo;
 
-import java.io.File;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.security.InvalidParameterException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.log4j.Logger;
-
 import com.cloud.exception.CloudException;
 import com.cloud.hypervisor.vmware.util.VmwareContext;
 import com.cloud.hypervisor.vmware.util.VmwareHelper;
@@ -92,6 +81,33 @@
 import com.vmware.vim25.VmwareDistributedVirtualSwitchPvlanSpec;
 import com.vmware.vim25.VmwareDistributedVirtualSwitchVlanIdSpec;
 import com.vmware.vim25.VmwareDistributedVirtualSwitchVlanSpec;
+import org.apache.log4j.Logger;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.traversal.DocumentTraversal;
+import org.w3c.dom.traversal.NodeFilter;
+import org.w3c.dom.traversal.NodeIterator;
+import org.xml.sax.SAXException;
+
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.StringWriter;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.security.InvalidParameterException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
 
 public class HypervisorHostHelper {
     private static final Logger s_logger = Logger.getLogger(HypervisorHostHelper.class);
@@ -1477,6 +1493,40 @@
         return url;
     }
 
+    public static String removeOVFNetwork(final String ovfString)  {
+        if (ovfString == null || ovfString.isEmpty()) {
+            return ovfString;
+        }
+        try {
+            final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+            final Document doc = factory.newDocumentBuilder().parse(new ByteArrayInputStream(ovfString.getBytes()));
+            final DocumentTraversal traversal = (DocumentTraversal) doc;
+            final NodeIterator iterator = traversal.createNodeIterator(doc.getDocumentElement(), NodeFilter.SHOW_ELEMENT, null, true);
+            for (Node n = iterator.nextNode(); n != null; n = iterator.nextNode()) {
+                final Element e = (Element) n;
+                if ("NetworkSection".equals(e.getTagName())) {
+                    if (e.getParentNode() != null) {
+                        e.getParentNode().removeChild(e);
+                    }
+                } else if ("rasd:Connection".equals(e.getTagName())) {
+                    if (e.getParentNode() != null && e.getParentNode().getParentNode() != null) {
+                        e.getParentNode().getParentNode().removeChild(e.getParentNode());
+                    }
+                }
+            }
+            final DOMSource domSource = new DOMSource(doc);
+            final StringWriter writer = new StringWriter();
+            final StreamResult result = new StreamResult(writer);
+            final TransformerFactory tf = TransformerFactory.newInstance();
+            final Transformer transformer = tf.newTransformer();
+            transformer.transform(domSource, result);
+            return writer.toString();
+        } catch (SAXException | IOException | ParserConfigurationException | TransformerException e) {
+            s_logger.warn("Unexpected exception caught while removing network elements from OVF:", e);
+        }
+        return ovfString;
+    }
+
     public static void importVmFromOVF(VmwareHypervisorHost host, String ovfFilePath, String vmName, DatastoreMO dsMo, String diskOption, ManagedObjectReference morRp,
             ManagedObjectReference morHost) throws Exception {
 
@@ -1488,9 +1538,9 @@
         importSpecParams.setEntityName(vmName);
         importSpecParams.setDeploymentOption("");
         importSpecParams.setDiskProvisioning(diskOption); // diskOption: thin, thick, etc
-        //importSpecParams.setPropertyMapping(null);
 
-        String ovfDescriptor = HttpNfcLeaseMO.readOvfContent(ovfFilePath);
+        String ovfDescriptor = removeOVFNetwork(HttpNfcLeaseMO.readOvfContent(ovfFilePath));
+
         VmwareContext context = host.getContext();
         OvfCreateImportSpecResult ovfImportResult =
                 context.getService().createImportSpec(context.getServiceContent().getOvfManager(), ovfDescriptor, morRp, dsMo.getMor(), importSpecParams);
diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/mo/VmwareHypervisorHost.java b/vmware-base/src/com/cloud/hypervisor/vmware/mo/VmwareHypervisorHost.java
index fdfc254..0767ec0 100644
--- a/vmware-base/src/com/cloud/hypervisor/vmware/mo/VmwareHypervisorHost.java
+++ b/vmware-base/src/com/cloud/hypervisor/vmware/mo/VmwareHypervisorHost.java
@@ -37,6 +37,10 @@
 
     ClusterDasConfigInfo getDasConfig() throws Exception;
 
+    boolean isHAEnabled() throws Exception;
+
+    void setRestartPriorityForVM(VirtualMachineMO vmMo, String priority) throws Exception;
+
     ManagedObjectReference getHyperHostDatacenter() throws Exception;
 
     ManagedObjectReference getHyperHostOwnerResourcePool() throws Exception;
diff --git a/vmware-base/test/com/cloud/hypervisor/vmware/mo/HypervisorHostHelperTest.java b/vmware-base/test/com/cloud/hypervisor/vmware/mo/HypervisorHostHelperTest.java
index 6997805..2fc9995 100644
--- a/vmware-base/test/com/cloud/hypervisor/vmware/mo/HypervisorHostHelperTest.java
+++ b/vmware-base/test/com/cloud/hypervisor/vmware/mo/HypervisorHostHelperTest.java
@@ -16,22 +16,7 @@
 // under the License.
 package com.cloud.hypervisor.vmware.mo;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.assertNull;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
-import static org.mockito.Mockito.when;
-
-import org.junit.After;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
+import com.cloud.hypervisor.vmware.util.VmwareContext;
 import com.vmware.vim25.AboutInfo;
 import com.vmware.vim25.BoolPolicy;
 import com.vmware.vim25.DVPortgroupConfigInfo;
@@ -41,8 +26,21 @@
 import com.vmware.vim25.ServiceContent;
 import com.vmware.vim25.VMwareDVSPortSetting;
 import com.vmware.vim25.VmwareDistributedVirtualSwitchVlanIdSpec;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
 
-import com.cloud.hypervisor.vmware.util.VmwareContext;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.when;
 
 public class HypervisorHostHelperTest {
     @Mock
@@ -557,4 +555,223 @@
         String cloudNetworkName = HypervisorHostHelper.composeCloudNetworkName(prefix, vlanId, svlanId, networkRateMbps, vSwitchName);
         assertEquals("cloud.guest.400.s123.512.1-vSwitch2", cloudNetworkName);
     }
+
+    @Test
+    public void testOvfDomRewriter() {
+        final String ovfString = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
+                "<!--Generated by VMware ovftool 3.5.0 (build-1274719), UTC time: 2016-10-03T12:49:55.591821Z-->" +
+                "<Envelope xmlns=\"http://schemas.dmtf.org/ovf/envelope/1\" xmlns:cim=\"http://schemas.dmtf.org/wbem/wscim/1/common\" xmlns:ovf=\"http://schemas.dmtf.org/ovf/envelope/1\" xmlns:rasd=\"http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData\" xmlns:vmw=\"http://www.vmware.com/schema/ovf\" xmlns:vssd=\"http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_VirtualSystemSettingData\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n" +
+                "  <References>\n" +
+                "    <File ovf:href=\"macchinina-vmware-disk1.vmdk\" ovf:id=\"file1\" ovf:size=\"23303168\"/>\n" +
+                "  </References>\n" +
+                "  <DiskSection>\n" +
+                "    <Info>Virtual disk information</Info>\n" +
+                "    <Disk ovf:capacity=\"50\" ovf:capacityAllocationUnits=\"byte * 2^20\" ovf:diskId=\"vmdisk1\" ovf:fileRef=\"file1\" ovf:format=\"http://www.vmware.com/interfaces/specifications/vmdk.html#streamOptimized\" ovf:populatedSize=\"43319296\"/>\n" +
+                "  </DiskSection>\n" +
+                "  <NetworkSection>\n" +
+                "    <Info>The list of logical networks</Info>\n" +
+                "    <Network ovf:name=\"bridged\">\n" +
+                "      <Description>The bridged network</Description>\n" +
+                "    </Network>\n" +
+                "  </NetworkSection>\n" +
+                "  <VirtualSystem ovf:id=\"vm\">\n" +
+                "    <Info>A virtual machine</Info>\n" +
+                "    <Name>macchinina-vmware</Name>\n" +
+                "    <OperatingSystemSection ovf:id=\"101\" vmw:osType=\"otherLinux64Guest\">\n" +
+                "      <Info>The kind of installed guest operating system</Info>\n" +
+                "    </OperatingSystemSection>\n" +
+                "    <VirtualHardwareSection>\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>macchinina-vmware</vssd:VirtualSystemIdentifier>\n" +
+                "        <vssd:VirtualSystemType>vmx-07</vssd:VirtualSystemType>\n" +
+                "      </System>\n" +
+                "      <Item>\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:ResourceType>3</rasd:ResourceType>\n" +
+                "        <rasd:VirtualQuantity>1</rasd:VirtualQuantity>\n" +
+                "      </Item>\n" +
+                "      <Item>\n" +
+                "        <rasd:AllocationUnits>byte * 2^20</rasd:AllocationUnits>\n" +
+                "        <rasd:Description>Memory Size</rasd:Description>\n" +
+                "        <rasd:ElementName>256MB of memory</rasd:ElementName>\n" +
+                "        <rasd:InstanceID>2</rasd:InstanceID>\n" +
+                "        <rasd:ResourceType>4</rasd:ResourceType>\n" +
+                "        <rasd:VirtualQuantity>256</rasd:VirtualQuantity>\n" +
+                "      </Item>\n" +
+                "      <Item>\n" +
+                "        <rasd:Address>0</rasd:Address>\n" +
+                "        <rasd:Description>SCSI Controller</rasd:Description>\n" +
+                "        <rasd:ElementName>scsiController0</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>ideController0</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>false</rasd:AutomaticAllocation>\n" +
+                "        <rasd:ElementName>cdrom0</rasd:ElementName>\n" +
+                "        <rasd:InstanceID>5</rasd:InstanceID>\n" +
+                "        <rasd:Parent>4</rasd:Parent>\n" +
+                "        <rasd:ResourceType>15</rasd:ResourceType>\n" +
+                "      </Item>\n" +
+                "      <Item>\n" +
+                "        <rasd:AddressOnParent>0</rasd:AddressOnParent>\n" +
+                "        <rasd:ElementName>disk0</rasd:ElementName>\n" +
+                "        <rasd:HostResource>ovf:/disk/vmdisk1</rasd:HostResource>\n" +
+                "        <rasd:InstanceID>6</rasd:InstanceID>\n" +
+                "        <rasd:Parent>3</rasd:Parent>\n" +
+                "        <rasd:ResourceType>17</rasd:ResourceType>\n" +
+                "      </Item>\n" +
+                "      <Item>\n" +
+                "        <rasd:AddressOnParent>2</rasd:AddressOnParent>\n" +
+                "        <rasd:AutomaticAllocation>true</rasd:AutomaticAllocation>\n" +
+                "        <rasd:Connection>bridged</rasd:Connection>\n" +
+                "        <rasd:Description>E1000 ethernet adapter on &quot;bridged&quot;</rasd:Description>\n" +
+                "        <rasd:ElementName>ethernet0</rasd:ElementName>\n" +
+                "        <rasd:InstanceID>7</rasd:InstanceID>\n" +
+                "        <rasd:ResourceSubType>E1000</rasd:ResourceSubType>\n" +
+                "        <rasd:ResourceType>10</rasd:ResourceType>\n" +
+                "        <vmw:Config ovf:required=\"false\" vmw:key=\"wakeOnLanEnabled\" vmw:value=\"false\"/>\n" +
+                "      </Item>\n" +
+                "      <Item ovf:required=\"false\">\n" +
+                "        <rasd:AutomaticAllocation>false</rasd:AutomaticAllocation>\n" +
+                "        <rasd:ElementName>video</rasd:ElementName>\n" +
+                "        <rasd:InstanceID>8</rasd:InstanceID>\n" +
+                "        <rasd:ResourceType>24</rasd:ResourceType>\n" +
+                "        <vmw:Config ovf:required=\"false\" vmw:key=\"enable3DSupport\" vmw:value=\"false\"/>\n" +
+                "        <vmw:Config ovf:required=\"false\" vmw:key=\"useAutoDetect\" vmw:value=\"false\"/>\n" +
+                "        <vmw:Config ovf:required=\"false\" vmw:key=\"videoRamSizeInKB\" vmw:value=\"4096\"/>\n" +
+                "      </Item>\n" +
+                "      <Item ovf:required=\"false\">\n" +
+                "        <rasd:AutomaticAllocation>false</rasd:AutomaticAllocation>\n" +
+                "        <rasd:ElementName>vmci</rasd:ElementName>\n" +
+                "        <rasd:InstanceID>9</rasd:InstanceID>\n" +
+                "        <rasd:ResourceSubType>vmware.vmci</rasd:ResourceSubType>\n" +
+                "        <rasd:ResourceType>1</rasd:ResourceType>\n" +
+                "      </Item>\n" +
+                "      <vmw:Config ovf:required=\"false\" vmw:key=\"cpuHotAddEnabled\" vmw:value=\"false\"/>\n" +
+                "      <vmw:Config ovf:required=\"false\" vmw:key=\"cpuHotRemoveEnabled\" vmw:value=\"false\"/>\n" +
+                "      <vmw:Config ovf:required=\"false\" vmw:key=\"firmware\" vmw:value=\"bios\"/>\n" +
+                "      <vmw:Config ovf:required=\"false\" vmw:key=\"memoryHotAddEnabled\" vmw:value=\"false\"/>\n" +
+                "    </VirtualHardwareSection>\n" +
+                "    <AnnotationSection ovf:required=\"false\">\n" +
+                "      <Info>A human-readable annotation</Info>\n" +
+                "      <Annotation>macchinina-vmware</Annotation>\n" +
+                "    </AnnotationSection>\n" +
+                "  </VirtualSystem>\n" +
+                "</Envelope>";
+
+        final String expected = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
+                "<!--Generated by VMware ovftool 3.5.0 (build-1274719), UTC time: 2016-10-03T12:49:55.591821Z-->" +
+                "<Envelope xmlns=\"http://schemas.dmtf.org/ovf/envelope/1\" xmlns:cim=\"http://schemas.dmtf.org/wbem/wscim/1/common\" xmlns:ovf=\"http://schemas.dmtf.org/ovf/envelope/1\" xmlns:rasd=\"http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData\" xmlns:vmw=\"http://www.vmware.com/schema/ovf\" xmlns:vssd=\"http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_VirtualSystemSettingData\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n" +
+                "  <References>\n" +
+                "    <File ovf:href=\"macchinina-vmware-disk1.vmdk\" ovf:id=\"file1\" ovf:size=\"23303168\"/>\n" +
+                "  </References>\n" +
+                "  <DiskSection>\n" +
+                "    <Info>Virtual disk information</Info>\n" +
+                "    <Disk ovf:capacity=\"50\" ovf:capacityAllocationUnits=\"byte * 2^20\" ovf:diskId=\"vmdisk1\" ovf:fileRef=\"file1\" ovf:format=\"http://www.vmware.com/interfaces/specifications/vmdk.html#streamOptimized\" ovf:populatedSize=\"43319296\"/>\n" +
+                "  </DiskSection>\n  \n" +
+                "  <VirtualSystem ovf:id=\"vm\">\n" +
+                "    <Info>A virtual machine</Info>\n" +
+                "    <Name>macchinina-vmware</Name>\n" +
+                "    <OperatingSystemSection ovf:id=\"101\" vmw:osType=\"otherLinux64Guest\">\n" +
+                "      <Info>The kind of installed guest operating system</Info>\n" +
+                "    </OperatingSystemSection>\n" +
+                "    <VirtualHardwareSection>\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>macchinina-vmware</vssd:VirtualSystemIdentifier>\n" +
+                "        <vssd:VirtualSystemType>vmx-07</vssd:VirtualSystemType>\n" +
+                "      </System>\n" +
+                "      <Item>\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:ResourceType>3</rasd:ResourceType>\n" +
+                "        <rasd:VirtualQuantity>1</rasd:VirtualQuantity>\n" +
+                "      </Item>\n" +
+                "      <Item>\n" +
+                "        <rasd:AllocationUnits>byte * 2^20</rasd:AllocationUnits>\n" +
+                "        <rasd:Description>Memory Size</rasd:Description>\n" +
+                "        <rasd:ElementName>256MB of memory</rasd:ElementName>\n" +
+                "        <rasd:InstanceID>2</rasd:InstanceID>\n" +
+                "        <rasd:ResourceType>4</rasd:ResourceType>\n" +
+                "        <rasd:VirtualQuantity>256</rasd:VirtualQuantity>\n" +
+                "      </Item>\n" +
+                "      <Item>\n" +
+                "        <rasd:Address>0</rasd:Address>\n" +
+                "        <rasd:Description>SCSI Controller</rasd:Description>\n" +
+                "        <rasd:ElementName>scsiController0</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>ideController0</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>false</rasd:AutomaticAllocation>\n" +
+                "        <rasd:ElementName>cdrom0</rasd:ElementName>\n" +
+                "        <rasd:InstanceID>5</rasd:InstanceID>\n" +
+                "        <rasd:Parent>4</rasd:Parent>\n" +
+                "        <rasd:ResourceType>15</rasd:ResourceType>\n" +
+                "      </Item>\n" +
+                "      <Item>\n" +
+                "        <rasd:AddressOnParent>0</rasd:AddressOnParent>\n" +
+                "        <rasd:ElementName>disk0</rasd:ElementName>\n" +
+                "        <rasd:HostResource>ovf:/disk/vmdisk1</rasd:HostResource>\n" +
+                "        <rasd:InstanceID>6</rasd:InstanceID>\n" +
+                "        <rasd:Parent>3</rasd:Parent>\n" +
+                "        <rasd:ResourceType>17</rasd:ResourceType>\n" +
+                "      </Item>\n      \n" +
+                "      <Item ovf:required=\"false\">\n" +
+                "        <rasd:AutomaticAllocation>false</rasd:AutomaticAllocation>\n" +
+                "        <rasd:ElementName>video</rasd:ElementName>\n" +
+                "        <rasd:InstanceID>8</rasd:InstanceID>\n" +
+                "        <rasd:ResourceType>24</rasd:ResourceType>\n" +
+                "        <vmw:Config ovf:required=\"false\" vmw:key=\"enable3DSupport\" vmw:value=\"false\"/>\n" +
+                "        <vmw:Config ovf:required=\"false\" vmw:key=\"useAutoDetect\" vmw:value=\"false\"/>\n" +
+                "        <vmw:Config ovf:required=\"false\" vmw:key=\"videoRamSizeInKB\" vmw:value=\"4096\"/>\n" +
+                "      </Item>\n" +
+                "      <Item ovf:required=\"false\">\n" +
+                "        <rasd:AutomaticAllocation>false</rasd:AutomaticAllocation>\n" +
+                "        <rasd:ElementName>vmci</rasd:ElementName>\n" +
+                "        <rasd:InstanceID>9</rasd:InstanceID>\n" +
+                "        <rasd:ResourceSubType>vmware.vmci</rasd:ResourceSubType>\n" +
+                "        <rasd:ResourceType>1</rasd:ResourceType>\n" +
+                "      </Item>\n" +
+                "      <vmw:Config ovf:required=\"false\" vmw:key=\"cpuHotAddEnabled\" vmw:value=\"false\"/>\n" +
+                "      <vmw:Config ovf:required=\"false\" vmw:key=\"cpuHotRemoveEnabled\" vmw:value=\"false\"/>\n" +
+                "      <vmw:Config ovf:required=\"false\" vmw:key=\"firmware\" vmw:value=\"bios\"/>\n" +
+                "      <vmw:Config ovf:required=\"false\" vmw:key=\"memoryHotAddEnabled\" vmw:value=\"false\"/>\n" +
+                "    </VirtualHardwareSection>\n" +
+                "    <AnnotationSection ovf:required=\"false\">\n" +
+                "      <Info>A human-readable annotation</Info>\n" +
+                "      <Annotation>macchinina-vmware</Annotation>\n" +
+                "    </AnnotationSection>\n" +
+                "  </VirtualSystem>\n" +
+                "</Envelope>";
+        assertEquals(expected, HypervisorHostHelper.removeOVFNetwork(ovfString));
+    }
 }